简体   繁体   中英

React Router Question: why history.push changes url but doesn't update component

Below is a sample code that renders two buttons (home and about) and two page component (also Home and About). Upon clicking each button, the buttons would call history.push to go to the respective page and should render the component.

However, what I notice is that when a button is clicked, the url changes but the component doesn't show up. I manage to get this fixed by passing the { forceRefresh: true } property when creating browser history like this const history = createBrowserHistory({ forceRefresh: true }); Still, I don't quite understand why this occur and why forceRefresh solves the problem and would appreciate any explanation.

That reason I didn't use the <Link> component to wrap around the button is because I want to call a function to execute something before redirecting when the button is clicked. If there is another way to do this, I would love to know from the community. Thanks.

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import { createBrowserHistory } from 'history';

const MyApp = () => {
    const history = createBrowserHistory();
    return (
        <Router history={history}>
            <div>
                <ul>
                    <li>
                        <button onClick={() => history.push('/')}>Home</button>
                    </li>
                    <li>
                        <button onClick={() => history.push('/about')}>About</button>
                    </li>
                </ul>

                <Switch>
                    <Route exact path='/'>
                        <Home />
                    </Route>
                    <Route exact path='/about'>
                        <About />
                    </Route>
                </Switch>
            </div>
        </Router>
    );
};
function Home() {
    return (
        <div>
            <h2>Home</h2>
        </div>
    );
}

function About() {
    return (
        <div>
            <h2>About</h2>
        </div>
    );
}

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

This is because of this line:

const history = createBrowserHistory();

You are instantiating a history object which will be used by Router to keep track of the routing history. This is something used under the hood by Router and you shouldn't need to worry about it.

What you're doing wrong is to think that the history variable you declared there (use by Router ) is the same used to navigate through the app. It's not.

You should use this history to navigate:

import { useHistory } from 'react-router-dom'

Usage:

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import { createBrowserHistory } from 'history';
import { useHistory } from 'react-router-dom';

const MyApp = () => {
    const historyInstance = createBrowserHistory();

    const history = useHistory();

    return (
        <Router history={historyInstance}>
            <div>
                <ul>
                    <li>
                        <button onClick={() => history.push('/')}>Home</button>
                    </li>
                    <li>
                        <button onClick={() => history.push('/about')}>About</button>
                    </li>
                </ul>

                <Switch>
                    <Route exact path='/'>
                        <Home />
                    </Route>
                    <Route exact path='/about'>
                        <About />
                    </Route>
                </Switch>
            </div>
        </Router>
    );
};

And with that, everything should work

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM