简体   繁体   中英

React js: React router not redirecting when button is being clicked

I have been trying to solve this problem for couple days and still couldnt get it to work. How does redirecting not work here? I keep getting the "TypeError: history is undefined". Also when the button is being clicked, it stays at the same url. What am I doing wrong?

import React from 'react';
import Nav from './Nav';
import About from './About';
import Service from './Service';
import Home from './Home';
import {
    BrowserRouter as Router,
    Switch,
    Route,
    useHistory,
} from 'react-router-dom';

function App() {
    const history = useHistory();
    function handleSub() {
        // console.log('clicked');
        history.push('/about');
    }
    return (
        <div className='App'>
            <button onClick={handleSub}>submit</button>
            <Router>
                <Nav />
                <Switch>
                    <Route path='/' exact component={Home} />
                    <Route path='/about' component={About} />
                    <Route path='/service' component={Service} />
                </Switch>
            </Router>
        </div>
    );
}

export default App;

Edit: implemented the answers and still having trouble. Suggestion 1: place the button inside the router: url switches for links or button is clicked but pages for the links not when the button is clicked.

function App() {
const history = useHistory();
function handleSub() {
    // console.log('clicked');
    history.push(`/about`);
}
return (
    <Router>
        <div className='App'>
            <Nav />
            <button onClick={handleSub}>submit</button>
            <Switch>
                <Route path='/' exact component={Home} />
                <Route path='/about' component={About} />
                <Route path='/service' component={Service} />
            </Switch>
        </div>
    </Router>
);

}

Suggestion number two: url swtich for all the links and button but the page never loads.

function App() {
    const history = useHistory();
    function handleSub() {
        // console.log('clicked');
        history.push(`/about`);
    }
    return (
        <Router>
            <div className='App'>
                <Nav />
                <Switch>
                    <button onClick={handleSub}>submit</button>
                    <Route path='/' exact component={Home} />
                    <Route path='/about' component={About} />
                    <Route path='/service' component={Service} />
                </Switch>
            </div>
        </Router>
    );
}

Simply because you are calling useHistory hook outside of React Router Switch Component, meaning you should use this hook in all Switch child components, otherwise the history object is undefined. The best way for my opinion is to move the button to the Home Component, then surly it will work.

I hope this answer helped you.

If you use it like this

<Button color='primary' onClick={handleSub('/about')}>Submit</Button>

and in your method do it like this.

    const handleSub = (path) => async (e) => {
    history.push(path)}

I hope it will solve your issue.

It's not the placement of the button which is the issue, but as originally mentioned, the placement of useHistory . The history hook is expecting context provided by the Router component - if you are familiar with useContext , it's exactly the same here. You must be calling useHistory inside a component which is a child of Router .

I'll mock an index.js file to demonstrate:

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';

const rootHtml = (
  <Router>
    <App />
  </Router>
);


ReactDOM.render(rootHtml, document.getElementById('root'));

Remove the original router in the App component. Now this top level router has the App component in scope and can provide it with history context for useHistory to use.

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