Search code examples
javascriptreactjsreact-routercomponentsreact-router-dom

React-cant see anything after using route


So I'm trying to make an app where you fill out a survey and then go to another page. I've tried using React Router for this. I followed a tutorial but when I try to render components with Route in them it doesn't seem to render. components without Route seem to work fine.

main app:

import Intro from "./pages/intro.js"

function App() {
  return (
    <div className="App">
      <Intro/>
    </div>
  );
}

export default App;

component with Route:

import { Routes, useNavigate, Route, Router } from 'react-router-dom';
import B1 from "./B1.js"

function Intro() {
  const navigate = useNavigate();

  const navigateToB1 = () => {
    navigate('./B1.js');
  };

  return (       
    <form>
      <h1>Walcome!</h1>
      <p><b>plase enter your name:</b></p>
      <label>
        Name:
        <input type="text" name="name" />
      </label>
      <input
        type="submit"
        id="sumbit"
        value="Submit"
        onClick={navigateToB1}
      />
    
      <Router>
        <Routes>
          <Route path="./B1.js" element={<B1 />} />
        </Routes>
      </Router>
    </form>
  );
}

export default Intro;

Solution

  • Issues

    The Intro component can't use the useNavigate hook since it's the component rendering the Router component that provides the routing context the useNavigate hook needs. Intro is also incorrectly using the low-level Router component which is missing a couple required props.

    Router

    interface RouterProps {
      basename?: string;
      children?: React.ReactNode;
      location: Partial<Location> | string; // <-- required!!
      navigationType?: NavigationType;
      navigator: Navigator;                 // <-- required!!
      static?: boolean;
    }
    

    The higher-level routers, (BrowserRouter, HashRouter, etc...) manage this themselves.

    The Intro component is also rendering a form element and not preventing the default form action from occurring when the form is submitted. Not doing this will result in reloading the page and remounting the entire React app.

    Solution

    Use one of the higher level routers and render it higher in the ReactTree than any component that needs to access its routing context.

    Example:

    App

    import { BroswerRouter } from "react-router-dom";
    import Intro from "./pages/intro.js";
    
    function App() {
      return (
        <div className="App">
          <BrowserRouter>
            <Intro />
          </BrowserRouter>
        </div>
      );
    }
    
    export default App;
    

    Intro

    Remove the router and consume the onSubmit event object in the navigateToB1 handler to prevent submitting the form.

    import { Routes, useNavigate, Route } from 'react-router-dom';
    import B1 from "./B1.js";
    
    function Intro() {
      const navigate = useNavigate();
    
      const navigateToB1 = (e) => { // <-- consume onSubmit event object
        e.preventDefault();         // <-- prevent the default form action
        navigate('/B1.js');
      };
    
      return (       
        <form>
          <h1>Welcome!</h1>
          <p><b>Please enter your name:</b></p>
          <label>
            Name:
            <input type="text" name="name" />
          </label>
          <input
            type="submit"
            id="submit"
            value="Submit"
            onClick={navigateToB1}
          />
        
          <Routes>
            <Route path="/B1.js" element={<B1 />} />
          </Routes> 
        </form>
      );
    }
    
    export default Intro;