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.