Home > Software engineering >  I'm working with React Route, and I have a random string, but when I do click on the link page
I'm working with React Route, and I have a random string, but when I do click on the link page

Time:12-10

I have a simple menu and I have a page with a random context only for tests. Here my index.js

const Route       = ReactRouterDOM.Route;
const Link        = ReactRouterDOM.Link;
const HashRouter  = ReactRouterDOM.HashRouter;
const Routes      = ReactRouterDOM.Routes;

// create context
const UserContext = React.createContext(null);

function Spa() {

    return (
    <HashRouter>
    <div>
    <h1>Routing - Hello World</h1>
    <Link to="/">Home</Link> --
    <Link to="/about/">About</Link> --
    <Link to="/products">Products</Link>
    <hr />
    <UserContext.Provider value={{ users: ["peter"] }}>
    <Routes>
    <Route path="/" exact element={ <Home />} />
    <Route path="/about/" element={ <About />} />
    <Route path="/products/" element={ <Products />} />
    </Routes>
    </UserContext.Provider>
    </div>
    </HashRouter>
    );
    }

    ReactDOM.render(
    <Spa/>,
    document.getElementById('root')
    ); 

and this is my products.js

    const ctx = React.useContext(UserContext);  
    ctx.users.push(Math.random().toString(36).substr(2, 5));

    return (
    <div>
    <h3>Products Component</h3>
    <p>List of the the product we make</p>
    {JSON.stringify(ctx.users)}
    </div>
   );
} 

my problem is that when I do click on the products menu the fist time the random works, but if I do again doesn't works, I have to change of link, for example login and return again to products for random works.

Someone knows what could be the problem?

I am using React-dom-16.8 History-5 React-Router-dom-6

CodePudding user response:

Use BrowserRouter instead of HashRouter

CodePudding user response:

Issues

  1. Linking to a route with the same path and state/etc is effectively a non-op. It won't trigger a navigation and it won't trigger the routed component to rerender.
  2. ctx.users.push(Math.random().toString(36).substr(2, 5)); is an unintentional side-effect and also won't trigger a rerender. You only see the mutation after navigating away and back to "/products".

Solution

  1. users should reside in some react state so when it's updated it can trigger React components to rerender. Pass the users state and the state updater (or some callback to update state) as the UserContext value.
  2. Pass some "random" state value in the link such that it will trigger the navigation action. Check for state in an useEffect to help trigger the effect to update the users state.

Suggestions

Spa

const Spa = () => {
  const [users, setUsers] = useState(["peter"]);
  return (
    <Router>
      <div>
        <h1>Routing - Hello World</h1>
        <Link to="/">Home</Link> --
        <Link to="/about/">About</Link> --
        <Link
          to="/products"
          state={{ value: Math.random() }} // <-- random state to trigger navigation
        >
          Products
        </Link>
        <hr />
        <UserContext.Provider value={{ users, setUsers }}>
          <Routes>
            <Route path="/" exact element={<Home />} />
            <Route path="/about/" element={<About />} />
            <Route path="/products/" element={<Products />} />
          </Routes>
        </UserContext.Provider>
      </div>
    </Router>
  );
};

Products

const Products = () => {
  const { state } = useLocation();
  const { users, setUsers } = useContext(UserContext);

  // "Listen" for updates to route state to trigger effect
  useEffect(() => {
    setUsers((users) => [...users, Math.random().toString(36).substr(2, 5)]);
  }, [state, setUsers]);

  return (
    <div>
      <h3>Products Component</h3>
      <p>List of the the product we make</p>
      {JSON.stringify(users)}
    </div>
  );
};

Edit im-working-with-react-route-and-i-have-a-random-string-but-when-i-do-click-on

  • Related