|
1 |
| -import { useReducer, useEffect } from 'react'; |
| 1 | +import { useReducer, useEffect, useCallback, useMemo } from 'react'; |
2 | 2 | import { useSelector } from 'react-redux';
|
3 | 3 | import { debounce } from 'lodash';
|
4 | 4 | import { Org } from 'constants/orgConstants';
|
@@ -88,47 +88,59 @@ export function useWorkspaceManager({
|
88 | 88 | }
|
89 | 89 | }, [isDropdownOpen, workspaces.totalCount]);
|
90 | 90 |
|
91 |
| - // API call to fetch workspaces |
92 |
| - const fetchWorkspacesPage = async (page: number, search?: string) => { |
93 |
| - dispatch({ type: 'SET_LOADING', payload: true }); |
94 |
| - |
95 |
| - try { |
96 |
| - const response = await UserApi.getMyOrgs(page, pageSize, search); |
97 |
| - if (response.data.success) { |
98 |
| - const apiData = response.data.data; |
99 |
| - const transformedItems = apiData.data.map(item => ({ |
100 |
| - id: item.orgId, |
101 |
| - name: item.orgName, |
102 |
| - })); |
103 |
| - |
| 91 | + // API call to fetch workspaces (memoized for stable reference) |
| 92 | + const fetchWorkspacesPage = useCallback( |
| 93 | + async (page: number, search?: string) => { |
| 94 | + dispatch({ type: 'SET_LOADING', payload: true }); |
| 95 | + |
| 96 | + try { |
| 97 | + const response = await UserApi.getMyOrgs(page, pageSize, search); |
| 98 | + if (response.data.success) { |
| 99 | + const apiData = response.data.data; |
| 100 | + const transformedItems = apiData.data.map(item => ({ |
| 101 | + id: item.orgId, |
| 102 | + name: item.orgName, |
| 103 | + })); |
| 104 | + |
| 105 | + dispatch({ |
| 106 | + type: 'SET_WORKSPACES', |
| 107 | + payload: { |
| 108 | + workspaces: transformedItems as Org[], |
| 109 | + total: apiData.total, |
| 110 | + }, |
| 111 | + }); |
| 112 | + } |
| 113 | + } catch (error) { |
| 114 | + console.error('Error fetching workspaces:', error); |
| 115 | + dispatch({ type: 'SET_WORKSPACES', payload: { workspaces: [], total: 0 } }); |
| 116 | + } |
| 117 | + }, |
| 118 | + [dispatch, pageSize] |
| 119 | + ); |
| 120 | + |
| 121 | + // Debounced search function (memoized to keep a single instance across renders) |
| 122 | + const debouncedSearch = useMemo(() => |
| 123 | + debounce(async (term: string) => { |
| 124 | + if (!term.trim()) { |
| 125 | + // Clear search - reset to Redux data |
104 | 126 | dispatch({
|
105 | 127 | type: 'SET_WORKSPACES',
|
106 |
| - payload: { |
107 |
| - workspaces: transformedItems as Org[], |
108 |
| - total: apiData.total, |
109 |
| - }, |
| 128 | + payload: { workspaces: [], total: workspaces.totalCount }, |
110 | 129 | });
|
| 130 | + return; |
111 | 131 | }
|
112 |
| - } catch (error) { |
113 |
| - console.error('Error fetching workspaces:', error); |
114 |
| - dispatch({ type: 'SET_WORKSPACES', payload: { workspaces: [], total: 0 } }); |
115 |
| - } |
116 |
| - }; |
117 | 132 |
|
118 |
| - // Debounced search function |
119 |
| - const debouncedSearch = debounce(async (term: string) => { |
120 |
| - if (!term.trim()) { |
121 |
| - // Clear search - reset to Redux data |
122 |
| - dispatch({ |
123 |
| - type: 'SET_WORKSPACES', |
124 |
| - payload: { workspaces: [], total: workspaces.totalCount } |
125 |
| - }); |
126 |
| - return; |
127 |
| - } |
| 133 | + // Perform search |
| 134 | + await fetchWorkspacesPage(1, term); |
| 135 | + }, 300) |
| 136 | + , [dispatch, fetchWorkspacesPage, workspaces.totalCount]); |
128 | 137 |
|
129 |
| - // Perform search |
130 |
| - await fetchWorkspacesPage(1, term); |
131 |
| - }, 300); |
| 138 | + // Cleanup debounce on unmount |
| 139 | + useEffect(() => { |
| 140 | + return () => { |
| 141 | + debouncedSearch.cancel(); |
| 142 | + }; |
| 143 | + }, [debouncedSearch]); |
132 | 144 |
|
133 | 145 | // Handle search input change
|
134 | 146 | const handleSearchChange = (value: string) => {
|
|
0 commit comments