3

I am doing a web application with react and I am getting this warning:

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

I have been looking for a solution but I haven't been able to fix the problem.

This is my code:

Main.jsx

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <BrowserRouter>
      <AuthProvider>
        <Routes>
          <Route path="/*" element={<App />} />
        </Routes>
      </AuthProvider>
    </BrowserRouter>
  </React.StrictMode>
)

App.jsx

Here, I separate the routes that require authentication. The ... means that there are some more routes there.

function App() {
  return (
    <Routes>
      <Route path='/' element={<Layout />}> 
        {/* public routes */}
        <Route element={<RequireNoAuth />}>
          <Route path='/login' element={<Login />} />
          <Route path='/register' element={<Register />} />
        </Route>

        {/* protected routes */}
        <Route element={<RequireAuth />}>
          <Route path='/' element={<Home />} />
          ...
        </Route>
      </Route>
    </Routes>
  )
}

Home.jsx

This is the file where the error occurs, specifically in the component AdministrationLayout, which I call the Contextprovider.

const Home = () => {
    return (
        <AdministrationLayout>
            <Container fluid>
                <Row>
                    <Col>
                        <h3>{i18n.t("dashboard.title")}</h3>
                    </Col>
                </Row>
            </Container>
        </AdministrationLayout>
    )
}

AdministrationLayout.jsx

const AdministrationLayout = ({ children }) => {
    return (
        <div className='cms-container'>
            <ContextProvider>
                <NavBar />
                <ContentContainer>
                    { children }
                </ContentContainer>
            </ContextProvider>
        </div>
    )
}

Finally, this is my contextProvider:

export const ContextProvider = ({ children }) => {
    const [showMenu, setShowMenu] = useState(true);
    const [activeMenu, setActiveMenu] = useState(readActiveMenu());
    const [screenSize, setScreenSize] = useState(undefined);

    const handleMenuClick = (menuSection) => {
        setActiveMenu(menuSection);
        saveActiveMenu(menuSection);
    }

    return (
        <StateContext.Provider
            value={{ showMenu, setShowMenu, activeMenu, setActiveMenu, screenSize, setScreenSize}}
        >
            { children }
        </StateContext.Provider>
    );
}

NavBar.jsx

const NavBar = () => {
    const auth = useAuth();
    const navigate = useNavigate();
    const location = useLocation();
    const from = location.state?.from?.pathname || "/";

    const { showMenu, setShowMenu, setActiveMenu } = useStateContext();
    const [showNotificationsOptions, setShowNotificationsOptions] = useState(false);
    const [showUserOptions, setShowUserOptions] = useState(false);

    const handleLogout = () => {
        setActiveMenu("dashboard");
        auth.logout();
        navigate(from, { replace: true });
    }

    const toogleNotificationsOptions = () => {
        setShowNotificationsOptions((prevState) => !prevState);
    }

    const toogleUserOptions = () => {
        setShowUserOptions((prevState) => !prevState);
    }

    return (
        <div className='navbar-container'>
            <div className='top-bar-container'>
                <div className='button-menu-container'>
                    <NavBarButton customFunction={setShowMenu((prevState) => !prevState)} icon={<FaBars />} classStyle='button-menu' />
                    <div className='title'>
                        <span>TEJIDOS</span>
                        <span>PULIDO</span>
                    </div>
                </div>
                <div className='session-menu-container'>
                    <NavBarButton customFunction={toogleNotificationsOptions} icon={<FaBell />} classStyle='button-menu' />
                    <div className='session-container'>
                        <div className='session-name'>{auth.token}</div>
                        <div className='session-button' onClick={toogleUserOptions}>
                            <FaUserAlt />
                            <FaChevronDown />

                            {(showUserOptions) 
                                ?   <div className='user-options-contianer'>
                                        <div onClick={handleLogout}>{i18n.t("shared.logout")}</div>
                                    </div>
                                :   null
                            }
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
  }
  • The error is probably in `Navbar` component. Please provide an example code of your code. I have no idea what the`Navbar` component does, but you may have called something like `navigate` inside its render. – c0m1t Aug 07 '22 at 16:58
  • Please edit your post to include ***all*** relevant code you are working with and have an issue using. See [mcve]. – Drew Reese Aug 07 '22 at 18:05
  • Any solution??? – martibellot Aug 14 '22 at 08:11

0 Answers0