JackBurton
JackBurton

Reputation: 263

React Parent Component not re-rendering

I have a parent component that renders a list of children pulled in from an API (which functions correctly). Each child has an option to delete itself. When a child deletes itself, I cannot get the parent to re-render. I have read about 50 answers on here related to this topic and tried all of them and nothing seems to be working. I am missing something and stuck.

The component has redux wired in to it, but I have tried the code with and without redux wired up. I have also tried this.forceUpdate() in the callback, which also does not work (I've commented it out in the example code below).

class Parent extends React.Component {
  constructor(props) {
    super(props)
    this.refresh = this.refresh.bind(this)
    this.state = {
      refresh: false,
    }
  }

  componentDidMount(){
    this.getChildren()
  }

  refresh = () => {
    console.log("State: ", this.state)
    this.setState({ refresh: !this.state.refresh })
    // this.forceUpdate();
    console.log("new state: ", this.state)
  }

  getChildren = () => {
    axios.get(
      config.api_url + `/api/children?page=${this.state.page}`,
      {headers: {token: ls('token')}
      }).then(resp => {
         this.setState({
           children: this.state.children.concat(resp.data.children)
           )}
         })
    }

  render(){
    return (

        <div>
             {_.map(this.state.children, (chidlren,i) =>
                <Children
                  key={i}
                  children={children}
                  refresh={() => this.refresh()}
                />
              )}
         </div>
    )
  }
}

And then in my Children component, which works perfectly fine, and the delete button successfully deletes the record from the database, I have the following excerpts:

  deleteChild = (e) => {
    e.preventDefault();
    axios.delete(
      config.api_url + `/api/children/${this.state.child.id}`,
      {headers: {token: ls('token')}}
    ).then(resp => {
      console.log("The response is: ", resp);
    })
    this.props.refresh();
    }

render() {
   return(
      <button class="btn" onClick={this.deleteChild}>Delete</button>
  )}
}

I am sure I am missing something simple or basic, but I can't find it.

Upvotes: 1

Views: 1506

Answers (2)

Padmika
Padmika

Reputation: 476

Your parent render method depends only on this.state.children which is not changing in your delete event. Either pass in the child id to your this.props.refresh method like this.props.refresh(this.state.child.id) and update this.state.children inside the refresh method or call the get children method again once a delete happens

Code for delete method in child

this.props.refresh(this.state.child.id)

Code for parent refresh method

refresh = (childIdToBeDeleted) => {
    console.log("State: ", this.state)
    this.setState({ refresh: !this.state.refresh })
    // this.forceUpdate();
    console.log("new state: ", this.state)

    //New code
    this.setState({children: this.state.children.filter(child => child.id !== childIdToBeDeleted);
  }

Upvotes: 1

Moti Korets
Moti Korets

Reputation: 3748

Few notes about the code. First removing from db and then reloading might be slow and not the best solution. Maybe consider adding remove() function which can be passed to the children component to update state more quickly.
Second if you want to call setState that depends on previous state it is better to use the callback method like this (but i think you need something else see below)

this.setState((prevState,prevProps) => 
   {children: prevState.children.concat(resp.data.children)})  

Lastly and what i think the issue is. You are not actually calling getChildren from refresh method so the state is not updated and if you want gonna reload the whole state from db you shouldn't concat but just set it like this

.then(resp => {
  this.setState({children: resp.data.children})
}

Hope it helps.

Edit: As mentioned in the comments the call to refresh from children should be in promise then

Upvotes: 0

Related Questions