Skip to content

RoomsTable: Side effect (setCurrent) called inside useMemo violates React rendering contract #40589

@SiddhiPandey08

Description

@SiddhiPandey08

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions