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?
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.
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))
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
Il te manque un/devant l'intro
<Route exact path="/" render={()=>(
Store.isFirstTime ? <Redirect to="/intro" /> : <Home state={Store} />
)} />
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
import { withRouter } from 'react-router-dom';
export default withRouter(MyComponent);
handlingButtonClick
handlingButtonClick = () => {
this.props.history.Push("/") //doing redirect here.
}