web-dev-qa-db-fra.com

React La redirection du routeur v4 ne fonctionne pas

J'ai un itinéraire qui redirige après avoir vérifié une condition comme celle-ci

<Route exact path="/" render={()=>(
Store.isFirstTime ? <Redirect to="intro" /> : <Home state={Store}/>)}/>

L'URL change lorsque la condition est vraie mais que le composant n'est pas monté. Le reste du code de composant est comme ci-dessous.

render() {
    return (
      <div>
        ...
        <Route exact path="/" render={()=>(
          Store.isFirstTime ? <Redirect to="intro" /> : <Home state={Store} />         
        )} />
        <Route path="/intro" render={()=>(<IntroWizard state={Store.userInfo}/>)} />
        <Route path="/home" render={()=>(<Home state={Store}/>)} />
        <Route render={()=>(<h1>404 Not Found</h1>)} />
        <Footer />
      </div>
    );
  }

Mon composant d'application est contenu dans le BrowserRouter, comme

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

lorsque je clique sur l'URL directement dans le navigateur, le composant 'localhost: 3000/intro' est monté correctement, mais lorsqu'il passe par la redirection, il ne l'affiche pas. Comment je le répare?

Modifier

Il manquait donc un détail et j'ai essayé de créer un autre projet pour reproduire le problème. Mon composant App est un observateur de mobx-react et il est exporté comme indiqué ci-dessous.

let App = observer(class App { ... })
export default App

J'ai créé ce dépôt avec un exemple de code pour reproduire le problème. Vous pouvez l'utiliser https://github.com/mdanishs/mobxtest/

Ainsi, lorsque les composants sont intégrés à l'observateur mobx-react, la redirection ne fonctionne pas, sinon elle fonctionne correctement.

23
mdanishs

Le demandeur a posté un numéro sur GitHub, et a obtenu ce apparemment non publié guide caché (modifier: maintenant publié ) qui m'a également aidé. Je l'affiche ici parce que j'ai rencontré le même problème et que je veux que les autres évitent notre douleur.

Le problème est que mobx-react et react-redux fournissent tous les deux leur propre fonction shouldComponentUpdate() qui ne vérifie que les modifications de prop, mais que react-router envoie l'état dans le contexte. Lorsque l'emplacement change, cela ne change aucun accessoire et ne déclenche donc pas de mise à jour.

La solution consiste à transmettre l'emplacement comme accessoire. Le guide ci-dessus répertorie plusieurs façons de procéder, mais le plus simple consiste simplement à envelopper le conteneur avec le composant d'ordre supérieur withRouter():

export default withRouter(observer(MyComponent))

ou, pour redux:

export default withRouter(connect(mapStateToProps)(MyComponent))
41
neurozero

Soyez prudent lorsque vous composez le routeur avec d'autres composants tels que des fournisseurs de traduction, des fournisseurs de thèmes, etc. Après un certain temps, j'ai constaté que votre application devait être strictement encapsulée par le routeur, comme ceci:

<Provider store={store}>
  <ThemeProvider theme={theme}>
    <TranslationProvider
      namespaces={['Common', 'Rental']}
      translations={translations}
      defaultNS={'Common'}
    >
      <Router>
        <App />
      </Router>
    </TranslationProvider>
  </ThemeProvider>
</Provider>

J'espère que ça aide quelqu'un

3
Kornelius

Il te manque un/devant l'intro

<Route exact path="/" render={()=>(
  Store.isFirstTime ? <Redirect to="/intro" /> : <Home state={Store} />         
)} />
2
Tyler McGinnis

Vous ne devriez rendre que Redirect dans votre méthode de rendu

render(){
   return (<Redirect to="/" />);
}

mais voici ma solution préférée sans utiliser le composant Redirect

  1. importer import { withRouter } from 'react-router-dom';
  2. export default withRouter(MyComponent);
  3. Enfin, dans votre méthode d’action, supposons que handlingButtonClick
    handlingButtonClick = () => {
        this.props.history.Push("/") //doing redirect here.
    }
1
nokieng