简体   繁体   中英

Can't get React component to update after setting state after Axios call

I have a React component that is supposed to display some categories. I'm working on allowing a user to edit the category. I display a form and then get the results back in editCategory . I'm then making an Axios call to a rails back end. The PUT request is successful, but then when I try to setState, it's still using the data from what categories was before the PUT request. So State is not updating.

I've tried doing a GET request after the PUT request and then trying to setState after with the GET results, but it still just pulls what State was before the PUT request. Although if I refresh, my changes are there. So the backend is working.

class Categories extends React.Component { 
 state = { categories: [], toggleEditCat: false,  }

  componentDidMount() {
   axios.get(`/api/menus/${this.props.menuId}/categories`)
     .then( res => {
     this.setState({ categories:res.data })
    })
  }

componentDidUpdate() {
  this.render()
}

editCategory = (name, description, id) => {
 const category = { name, description}
 axios.put(`/api/menus/${this.props.menuId}/categories/${id}`, { 
 category })

 axios.get(`/api/menus/${this.props.menuId}/categories`)
  .then(res => {
   this.setState({ categories: res.data }, () => 
   console.log(this.state.categories))
 })
}  

}

render () {
 return (
  <Segment>
    <div>
      return this.state.categories.map(c => {
      return (
       <ul key={c.id}>
        <h3>Category Name: {c.name}</h3> 
       </ul>
      )
    </div>
  </Segment>
 )
}

Is there a way to rerender after that PUT request to make sure when I make the second GET request, I'm getting updated results? I thought setState was supposed to rerender, but I think I'm missing something there. Thanks for any help.

You're not waiting for your PUT to finished before your GET

editCategory = (name, description, id) => {
  const category = { name, description}
  axios.put(
    `/api/menus/${this.props.menuId}/categories/${id}`, 
    { category }
  ).then(() => { // when put is finished, the fire get
    axios.get(`/api/menus/${this.props.menuId}/categories`)
      .then(res => {
        this.setState({ categories: res.data })
      })
  })
}

EDIT: it's actually nicer to write it as a proper promise chain instead of nesting promises:

editCategory = (name, description, id) => {
  const category = { name, description}
  axios.put(
    `/api/menus/${this.props.menuId}/categories/${id}`, 
    { category }
  ).then(() => { // when put is finished, the fire get
    return axios.get(`/api/menus/${this.props.menuId}/categories`)
  }).then(res => {
    this.setState({ categories: res.data })
  })
}

You are doing both put and get at the same time so you won't get updated values. You can use async await

Try with below code

editCategory = async (name, description, id) => {
 const category = { name, description}
 const updated = await axios.put(`/api/menus/${this.props.menuId}/categories/${id}`, {category });

 if(updated){
   axios.get(`/api/menus/${this.props.menuId}/categories`)
    .then(res => {
    this.setState({ categories: res.data }, () => 
     console.log(this.state.categories));
    });
  }  
}

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