Search code examples
redux-toolkitrtk-query

Update global state after RTK Query loads data


I've noticed a problem with splitting responsibilities in React components based on the fetched data using RTK Query.

Basically, I have two components like HomePage and NavigationComponent. On HomePage I'd like to fetch the information about the user so that I can modify NavigationComponent accordingly.

What I do inside HomePage:

import { setNavigationMode } from "features/nav/navSlice";

export default function HomePage() {
  const {data: user} = useGetUserDataQuery();
  const dispatch = useAppDispatch();
  const navMode = user ? "all-options" : "none";

  dispatch(setNavigationMode(navMode)); // here I change the default Navigation mode

  return <MainLayout>
    <Navigation/>
    <Content/>
    <Footer/>
  </MainLayout>;
}

The HomePage is a special Page when the NavigationComponent shouldn't display any options for the not logged-in user. Other pages present additional Logo and Title on Nav.

React communicates:

Warning: Cannot update a component (NavComponent) while rendering a different component (HomePage). To locate the bad setState() call inside HomePage, follow the stack trace as described in https://reactjs.org/link/setstate-in-render

Not sure what is the right way to follow. Whether the state should be changed in the GetUser query after it is loaded - that doesn't seem to be legit.


Solution

  • The solution was too obvious. The dispatch should be run in useEffect.

    import { setNavigationMode } from "features/nav/navSlice";
    
    export default function HomePage() {
      const {data: user} = useGetUserDataQuery();
      const dispatch = useAppDispatch();
      const navMode = user ? "all-options" : "none";
    
      // changed lines
      useEffect( () => {
        dispatch(setNavMode(navMode));
      }, [navMode, dispatch]);
      // /changed lines
    
      return <MainLayout>
        <Navigation/>
        <Content/>
        <Footer/>
      </MainLayout>;
    }
    

    Thank you @papa-xvii for the hint with changing the navMode after user login. That solves the second problem I had. However I cannot accept the answer as it does not solve the problem I described above.