skip to Main Content

I am trying to learn react router by following the below video but the problem is in my stackblitz there is no App.js.
So I have included everything inside index.tsx. but now I need to use this line —-> const [user, setUser] = useState(null);.

If I use this line I am getting the error, can you let me know how to fix it.

Error:
Providing my code snippet, sandbox and youtube tutorial below.

Invalid hook call. Hooks can only be called inside of the body of a
function component. This could happen for one of the following
reasons:

https://stackblitz.com/edit/react-9czykt?file=index.tsx,pages%2FProducts.tsx,pages%2FSingleProduct.tsx,pages%2FLogin.tsx,pages%2FDashboard.tsx,App.tsx

import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import { StyledEngineProvider } from '@mui/material/styles';
import Demo from './Demo';
import Home from './pages/Home';
import About from './pages/About';
import Products from './pages/Products';
import Error from './pages/Error';
import SharedLayout from './pages/SharedLayout';
import SingleProduct from './pages/SingleProduct';
import Dashboard from './pages/Dashboard';
import Login from './pages/Login';

import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { useState } from 'react';

const [user, setUser] = useState(null);

ReactDOM.createRoot(document.querySelector('#root')!).render(
  <React.StrictMode>
    <BrowserRouter>
      {/* <nav>our nav bar</nav> */}
      <Routes>
        <Route path="/" element={<SharedLayout />}>
          <Route index element={<Home />} />
          <Route path="about" element={<About />} />
          <Route path="products" element={<Products />} />
          <Route path="products/:productId" element={<SingleProduct />} />
          <Route path="login" element={<Login setUser={setUser} />} />
          <Route path="login" element={<Login setUser={setUser} />} />

          <Route path="*" element={<Error />} />
        </Route>
        {/* <Route path="dashboard" element={<div> dashboard</div>}>
          <Route path="stats" element={<div> stats</div>} />
        </Route> */}
      </Routes>
      <StyledEngineProvider injectFirst>
        <Demo />
      </StyledEngineProvider>
      {/* <footer>our footer</footer> */}
    </BrowserRouter>
  </React.StrictMode>
);

2

Answers


  1. The code is breaking the Rules of Hooks.

    Only Call Hooks from React Functions

    Don’t call Hooks from regular JavaScript functions. Instead, you can:

    • ✅ Call Hooks from React function components.
    • ✅ Call Hooks from custom Hooks.

    Create a root-level React component that can call the useState hook and render the router and routes.

    Example:

    import { useState } from 'react';
    import { createRoot } from 'react-dom/client';
    import { BrowserRouter, Routes, Route } from 'react-router-dom';
    import { StyledEngineProvider } from '@mui/material/styles';
    import Demo from './Demo';
    import Home from './pages/Home';
    import About from './pages/About';
    import Products from './pages/Products';
    import Error from './pages/Error';
    import SharedLayout from './pages/SharedLayout';
    import SingleProduct from './pages/SingleProduct';
    import Dashboard from './pages/Dashboard';
    import Login from './pages/Login';
    
    const App = () => {
      const [user, setUser] = useState(null);
    
      return (
        <BrowserRouter>
          <Routes>
            <Route path="/" element={<SharedLayout />}>
              <Route index element={<Home />} />
              <Route path="about" element={<About />} />
              <Route path="products" element={<Products />} />
              <Route path="products/:productId" element={<SingleProduct />} />
              <Route path="login" element={<Login setUser={setUser} />} />
              <Route path="login" element={<Login setUser={setUser} />} />
    
              <Route path="*" element={<Error />} />
            </Route>
          </Routes>
          <StyledEngineProvider injectFirst>
            <Demo />
          </StyledEngineProvider>
        </BrowserRouter>
      );
    };
    
    createRoot(document.querySelector('#root')!).render(
      <React.StrictMode>
        <App />
      </React.StrictMode>
    );
    
    Login or Signup to reply.
  2. The Problem is with this part of the code const [user, setUser] = useState(null);. React hooks (such as useState) can only be used inside the body of a functional component.

    Try moving the following part of your code to a separate component and also move useState to that component.

    export const App = () => {
      const [user, setUser] = useState(null);
    
      return (
        <BrowserRouter>
          {/* <nav>our nav bar</nav> */}
          <Routes>
            <Route path='/' element={<SharedLayout />}>
              <Route index element={<Home />} />
              <Route path='about' element={<About />} />
              <Route path='products' element={<Products />} />
              <Route path='products/:productId' element={<SingleProduct />} />
              <Route path='login' element={<Login setUser={setUser} />} />
              <Route path='login' element={<Login setUser={setUser} />} />
    
              <Route path='*' element={<Error />} />
            </Route>
            {/* <Route path="dashboard" element={<div> dashboard</div>}>
            <Route path="stats" element={<div> stats</div>} />
          </Route> */}
          </Routes>
          <StyledEngineProvider injectFirst>
            <Demo />
          </StyledEngineProvider>
          {/* <footer>our footer</footer> */}
        </BrowserRouter>
      )
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search