Home > Enterprise >  Redirect with axios response in react
Redirect with axios response in react

Time:07-30

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

  • Related