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...
