0
votes

React et antd: le routeur ne restitue pas les composants

J'ai une page Web simple avec des pages de connexion et de recherche. J'ai également une barre de navigation en haut pour permettre de basculer entre les deux. Le App.js base se App.js comme suit:

const Login = () => {
    return (
        <div>
            login
        </div>
    );
}

export default Login

const List = () => {
    return (
        <div>
            list
        </div>
    );
}

export default List

Maintenant, le BaseRouter et le CustomLayout sont plus que

import React from "react";
import {Menu} from 'antd';
import {Link} from "react-router-dom";

 const Navbar = () => {
    return (
        <div>
            <Menu mode="horizontal" theme={"dark"}>
                <Menu.Item key="list">
                    <Link to={"/list"}>List</Link>
                </Menu.Item>
                <Menu.Item key={"login"}>
                    <Link to={"/login"}>Sign in</Link>
                </Menu.Item>
            </Menu>
        </div>
    );
}

export default Navbar

et

const CustomLayout = ({children}) => {
    return(
        <>
        <Navbar/>
        {children}
        </>
    );
}

export default CustomLayout;

Maintenant, la barre de navigation ressemble à ceci

const BaseRouter = () => (
    <div>
        <Route exact path={"/list"} component={ItemsList}/>
        <Route path={"/login"} component={LoginForm}/>
    </div>
);

export default BaseRouter;

Gardons les composants simples:

const history = createBrowserHistory();

function App() {
    return (
        <Router history={history}>
            <CustomLayout>
                <Switch>
                    <BaseRouter/>
                </Switch>
            </CustomLayout>
        </Router>
    );
}

export default App;

Maintenant, le problème est que lorsque je clique sur des liens dans la barre de navigation, React ne restitue pas les composants même si l'itinéraire change. J'ai vu des centaines de réponses sur SO mais je n'arrive toujours pas à comprendre.
REMARQUE
Il est important pour moi d'éviter d'actualiser ou de recharger la page.
ÉDITER
Curieusement, lorsque je change Router en BrowserRotuer cela fonctionne bien, mais je ne peux pas utiliser ma propre histoire.


0 commentaires

4 Réponses :


0
votes

Changez votre BaseRouter partir de ceci:

const BaseRouter = () => (
    <div>
        <Route exact path="/list" component={ItemsList}/>
        <Route path="/login" component={LoginForm}/>
    </div>
);

export default BaseRouter;

Pour ça :

const BaseRouter = () => (
    <div>
        <Route exact path={"/list"} component={ItemsList}/>
        <Route path={"/login"} component={LoginForm}/>
    </div>
);

export default BaseRouter;


1 commentaires

Non, je suis désolé, cela n'a rien changé



0
votes

Je crois que vous ne pouvez pas avoir le div à l'intérieur du commutateur. Vous n'exposez pas les composants Route à votre instruction switch.

Par conséquent, votre URL change parce que votre Navbar la fait changer, mais votre commutateur ne sait pas quoi faire.

Essayez de changer votre routeur de base pour ceci:

const BaseRouter = () => (
    <Switch>
        <Route exact path={"/list"} component={ItemsList}/>
        <Route path={"/login"} component={LoginForm}/>
    </Switch>
);

export default BaseRouter;
const history = createBrowserHistory();

function App() {
    return (
        <Router history={history}>
            <CustomLayout>

                    <BaseRouter/>

            </CustomLayout>
        </Router>
    );
}

export default App;


1 commentaires

Non, je suis désolé, cela n'a rien changé



0
votes

Router est de bas niveau et attend de vous que vous gériez les choses. BrowserRouter synchronise déjà avec l'historique HTML5. Si vous voulez un Router , je pense que vous devez gérer vous-même la synchronisation (par exemple <Link onClick={() => history.push(href)}>) ou écouter l'historique pour détecter les changements. Voir Détecter le changement d'itinéraire avec react-router


2 commentaires

Cela explique-t-il pourquoi je recevais un avertissement: You cannot change the history of Router


C'est vrai, mais il existe des moyens beaucoup plus simples, par exemple useLocation hook



1
votes

pourquoi n'utilisez-vous pas BrowserRouter du BrowserRouter react-router-dom .

  • App.js : - utilisez BrowserRouter de BrowserRouter react-router-dom
import { useHistory } from 'react-router-dom'

const testFunctionComponent = () => {
  const history = useHistory()
  
  const handleClick = (urlPath) => {
    // you can do
    history.push(urlPath) // to go anywhere 
  }

  return (
    <>
      <button onClick={() => handleClick('/anypath')}>Click Me!<button>
    </>
  )
}
  • BaseRouter.js : - importer une Route depuis BaseRouter.js react-router-dom
import React from "react";
import {Menu} from 'antd';
import {Link} from "react-router-dom";

const Navbar = () => {
  return (
    <div>
      <Menu mode="horizontal" theme={"dark"}>
        <Menu.Item key={"list"}>
          <Link to="/list">List</Link>
        </Menu.Item>
        <Menu.Item key={"login"}>
          <Link to="/login">Sign in</Link>
        </Menu.Item>
      </Menu>
    </div>
  );
}

export default Navbar
  • Navbar.js : -
import { Route } from 'react-router-dom'

const BaseRouter = () => (
  <div>
    <Route exact path="/list" component={ItemsList}/>
    <Route path="/login" component={LoginForm}/>
  </div>
);

export default BaseRouter;

alors si vous voulez utiliser l' history : -

import { BrowserRouter as Router, Switch } from 'react-router-dom'

function App() {
  return (
    <Router>
      <CustomLayout>
        <Switch>
          <BaseRouter/>
        </Switch>
      </CustomLayout>
    </Router>
  );
}

export default App;


2 commentaires

À quiconque lit ceci: c'est le moyen le plus simple. J'ai également constaté que si vous utilisez BrowserRouter vous pouvez appeler props.history.push() dans le composant de votre props.history.push() .


Oui. C'est vrai pour tous les composants étant les enfants sous le BrowserRouter .