Description
In apps/meteor/client/views/admin/rooms/RoomsTable.tsx, a state setter (setCurrent(0)) is called inside a useMemo callback to reset pagination when the search text changes. Calling state setters inside useMemo is a side effect during render, which React explicitly prohibits — memos must be pure computations.
Affected File
apps/meteor/client/views/admin/rooms/RoomsTable.tsx
Problematic Code
const query = useDebouncedValue(
useMemo(() => {
if (searchText !== prevRoomFilterText.current) {
setCurrent(0); // side effect inside useMemo
}
return { ... };
}, [searchText, sortBy, ...]),
500,
);
Why It's Wrong
useMemo must be a pure computation with no side effects
- Calling
setCurrent here triggers a state update during render
- In React Strict Mode,
useMemo can be invoked multiple times, potentially firing setCurrent(0) more than once
prevRoomFilterText is updated in a useEffect which runs after render, creating a timing window where the condition fires incorrectly on intermediate re-renders
Proposed Fix
Move the pagination reset into a useEffect watching searchText, and remove the side effect from the memo:
useEffect(() => {
setCurrent(0);
prevRoomFilterText.current = searchText;
}, [searchText, setCurrent]);
And simplify the memo to a pure computation:
const query = useDebouncedValue(
useMemo(() => ({
filter: searchText || '',
sort: `{ "${sortBy}": ${sortDirection === 'asc' ? 1 : -1} }`,
count: itemsPerPage,
offset: current,
types: ...,
}), [searchText, sortBy, sortDirection, itemsPerPage, current, roomFilters.types]),
500,
);
Notes
Verified on develop branch. Checked UsersTable.tsx and ChannelsTable.tsx — neither has this pattern. Issue is isolated to RoomsTable.tsx.
Description
In
apps/meteor/client/views/admin/rooms/RoomsTable.tsx, a state setter (setCurrent(0)) is called inside auseMemocallback to reset pagination when the search text changes. Calling state setters insideuseMemois a side effect during render, which React explicitly prohibits — memos must be pure computations.Affected File
apps/meteor/client/views/admin/rooms/RoomsTable.tsxProblematic Code
Why It's Wrong
useMemomust be a pure computation with no side effectssetCurrenthere triggers a state update during renderuseMemocan be invoked multiple times, potentially firingsetCurrent(0)more than onceprevRoomFilterTextis updated in auseEffectwhich runs after render, creating a timing window where the condition fires incorrectly on intermediate re-rendersProposed Fix
Move the pagination reset into a
useEffectwatchingsearchText, and remove the side effect from the memo:And simplify the memo to a pure computation:
Notes
Verified on
developbranch. CheckedUsersTable.tsxandChannelsTable.tsx— neither has this pattern. Issue is isolated toRoomsTable.tsx.