I have a form Class Component, that uses Axios to submit to database. I want to wait for the Axios response so I can get the ID, then redirect using the ID in a route.
My problem is I keep getting
TypeError: this.props.navigate is not a function
Because useNavigate() can't be used in Class component. I tried using useHistory but it's deprecated and don't want to downgrade react.
handleSubmit(e){
e.preventDefault();
console.log("SUBMITTED")
const formData = new FormData();
formData.append('title',this.state.title);
formData.append('description',this.state.description);
formData.append('author',this.state.author);
formData.append('hashtags',this.state.hashtags);
formData.append('file',this.state.file);
axios.post('http://localhost:8002/upload',formData,{})
.then(res=>{
this.setState({id:res.data.zineCreated._id})
console.log(res.data.zineCreated._id)
console.log(res)
//history
let path = '/viewmyzine/62e0b9d44d0be19bd9e84bd5';
this.props.navigate(path); //not working
// this.props.navigation.navigate('/viewmyzine/62e0b9d44'); //not working
})
}
Outside the Class component I have
function WithNavigate(props) {
let navigate = useNavigate();
return <ViewZine test="NAGIVATE" navigate={navigate} />
}
But it still doesn't work
CodePudding user response:
Try rendering a <Navigate>
component only if you have an id state available. This is what the docs recommend.
Alternatively, you could call document.location.assign(path)
(or window.location.assign(path)
) if you wanted to reload the page, instead of using react router to handle a virtual location...
However, I was able to get a simplified version of your example (without using the Navigate
component) working:
import {useNavigate, BrowserRouter, Route, Routes} from 'react-router-dom'
import {Component} from 'react'
export default function App() {
return (
<div className="App">
<h1>Demo</h1>
<BrowserRouter>
<Routes>
<Route path='b' element={<blockquote>(at b)</blockquote>}/>
</Routes>
<NavigateWrapper />
</BrowserRouter>
</div>
);
}
function NavigateWrapper(props) {
const navigate = useNavigate()
return (<NavigateButton navigate={navigate} />)
}
class NavigateButton extends Component {
render() {
return <button onClick={event => this.callNavigate()}>call navigate</button>
}
callNavigate() {
alert(this.props.navigate)
this.props.navigate('b')
}
}
(see code sandbox example)
So it should be possible to pass navigate as a prop to a component element, and it should work. If this doesn't work, I would suspect that something is no longer rendered when the callback happens...