|
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