web-dev-qa-db-fra.com

React Router V4 met à jour l'URL, mais pas d'actualisation (React, Redux)

J'essaie d'utiliser React-Router V4 pour ajouter des itinéraires à mon application, mais cela ne fonctionne pas du tout. Fondamentalement, j'essaye de modifier la route par programmation avec history.Push, qui met à jour l'URL du navigateur, mais ne change rien dans l'application réelle.

NOTE: J'utilise redux.

La seule question à laquelle vous avez répondu à ce sujet est:

Réagissez history.Push () met à jour l'URL mais ne navigue pas dans le navigateur

Cependant, j'ai essayé de répondre à la question ci-dessus et cela ne fonctionne pas pour moi.

Voici les extraits importants:

Fichier le plus haut (index.js)

...
ReactDOM.render(
    <BrowserRouter>
        <Provider store={store}>
            <App/>
        </Provider>
    </BrowserRouter>
    , document.getElementById('root'));
...

Composant contenant des routes

...
export default function ContentRouter() {
    return <div className="content">
        <Route exact path="/dashboard" component={TmpDashboard}/>
        <Route exact path="/" component={() => {
            return <h1>Home</h1>
        }}/>
    </div>
}

Routes poussant des composants

...
this.handleGroupClick = (group) => {
    this.props.history.Push(`/groups/${group}`);
    this.props.onOpenChange(false);
};
...
export default withRouter(connect(mapStateToProps, mapDispatchToProps(DrawerConnector))

7
sunny-lan

Après de nombreuses recherches au mauvais endroit, j'ai compris ce qui n'allait pas. Le manque de mise à jour a été causé par Redux

Lorsqu'un composant est encapsulé dans connect, les mises à jour sont bloquées et l'affichage n'est pas mis à jour.

La solution est mentionnée ici:

https://github.com/ReactTraining/react-router/issues/4671#issuecomment-285320076

Fondamentalement, chaque composant avec un Route ou un objet React-Router à l'intérieur de celui-ci doit être entouré de withRouter

EDIT: seul le composant de niveau supérieur qui utilise connect doit être encapsulé dans withRouter. Notez que cela peut entraîner des problèmes de performances

EDIT: La manière dont je me suis débrouillé avec le couplage accru était d’avoir une composante juste pour traiter les itinéraires. De cette façon, je n'ai besoin que d'envelopper ce composant et le composant avec un routeur.

9
sunny-lan

Voici une configuration qui fonctionne:

L'application principale:

class App extends React.Component {

    render() {
        return (
            <BrowserRouter>
                <div>
                   /* this is a common component and happens to need to redirect */
                   <Route component={CommonComponentThatPushesToHistory} />
                   <div id="body">
                       /* I usually place this switch in a separate Routes file */
                       <Switch>
                           <Route exact path="FooRoute" component={FooPage}/>
                           <Route exact path="BarRoute" component={BarPage}/>
                        </Switch>
                   </div>
                   /* another common component which does not Push to history */
                   <Footer />
                </div>
            </BrowserRouter>
        );
    }
}

export default withRouter(App);

CommonComponentThatPushesToHistory

class CommonComponentThatPushesToHistory extends React.Component{
    render(){
        return(
            <button type="button" 
                onClick={() => {this.props.history.Push('some-page');}}>
                Click to get redirected</button>
        );
    }
}

FooPage peut avoir un composant enfant qui pousse à l'historique:

class FooPage extends React.Component{
    render(){
        return(
            <MyChild history={this.props.history} />
        );
    }
}

Ensuite, le composant MyChild peut transmettre à l'historique de la même manière que CommonComponentThatPushesToHistory.

0
Hossein