Cannot render component while rendering another. /React

Viewed 28

I have two components which update an array of routes on button click. On each button click I click to another route and update the routes array with the window.location.pathname. But when coming back to the firs component I get the following error :

Cannot update a component (App) while rendering a different component (Home). To locate the bad setState() call inside Home

First component :

function App() {
  const [user, setUser] = useState(0);
  const [path, setPath] = useState([]);

  return (
    <div className="App">
      <Provider store={store}>
        <userContext.Provider value={{ user, setUser }}>
          <pagesContext.Provider value={{ path, setPath }}>
            <Routes>
              <Route exact path="/" element={<HomePage />}></Route>
              <Route path="/about" element={<AboutPage />}></Route>
              <Route path="/review" element={<ReviewPage />}></Route>
            </Routes>
          </pagesContext.Provider>
        </userContext.Provider>
      </Provider>
    </div>
  );
}
export default App;

Second component :

 const Home = () => {
  const datas = useSelector(selectHomeUsers);
  const { setUser } = useContext(userContext);
  const { path, setPath } = useContext(pagesContext);

  let navigate = useNavigate();

  setUser(0);

  const routes = [
    { id: 1, path: "/", element: <HomePage /> },
    { id: 2, path: "/about", element: <AboutPage /> },
    { id: 3, path: "/review", element: <ReviewPage /> },
  ];

  let i;
  const makeNext = (size, step = 2) => {
    i = size - step;

    return () => {
      i += step;
      if (i >= size) i -= size;
      return i;
    };
  };

  const nextId = makeNext(routes.length);

  const nextURL = () => {
    return routes[nextId()].path;
  };

  return (
    <div>
      <h1>Users:</h1>
      {datas.map((data) => {
        return <h1 key={data.id}>{data.name}</h1>;
      })}

      <button
        type="button"
        onClick={() => {
          // console.log(nextURL());
          setPath((path) => [...path, window.location.pathname]);
          nextURL();
          navigate(nextURL());
        }}
      >
        Go 2 urls Forward
      </button>
      <button
        type="button"
        onClick={() => {
          navigate(-2);
        }}
      >
        Go two urls backwards
      </button>
    </div>
  );
};

export default Home;
1 Answers

So your problem is coming from the Second component "Home". On every render setUser(0) is being triggered during App render since setUser is not wrapped in a useEffect. Usually you should be wrapping your setState function in useEffects when using them outside of the JSX in a procedural sense to prevent re-render issues, unless they are in a handler.

heres some offical documentation in relation to the error

// Home.jsx
useEffect(()=>{
  setUser(0)
},
[setUser])
Related