Dimitry Ivashchuk
Dimitry Ivashchuk

Reputation: 625

Triggering update of parent component on child state change

I am exploring firebase using React as a frontend framework and got stuck on a following problem:

I have the following parent component with a lifecycle hook that gets my data from firebase and populates a local state with it. After that the component outputs the state .

state = {
    pets: null
  };

  componentDidMount() {
    db
      .onceGetPets()
      .then(snapshot => this.setState(() => ({ pets: snapshot.val() })));
  }

  render() {
    const {pets} = this.state;
     return ({pets})}

I also have a child component that writes new entries into the data base and looks the following way:

state = {
    ...INITIAL_STATE
  };

  submitHandler = event => {
    const { name, age, animal, breed } = this.state;

    db.doCreatePet(
      name,
      age,
      animal,
      breed,
      auth.currentUser.email.slice(0, -4)
    );
    this.setState({ ...INITIAL_STATE });
    event.preventDefault();
  };
    render(){
      return(<StyledNewPetForm show={this.props.show} onSubmit={this.submitHandler}/>)}

I want to achieve the following behavior:

When user submits the form(child component) it should trigger rerender of parent component(the one that displays data) that would in turn get new data from firebase and display it.

Upvotes: 1

Views: 759

Answers (2)

kumar k
kumar k

Reputation: 476

Instead of calling the pets data in componentDidMount, move it to separate function like below and bind the function in the constructor.

fetchPetData(){
 db
      .onceGetPets()
      .then(snapshot => this.setState(() => ({ pets: snapshot.val() })));
}

and call the function in componentDidMount as below

componentDidMount() {
    this.fetchPetData();
  }

Then you can pass the function as props to child component and call the function in child component in submit function as below.

this.props.fetchPetData();

and in the parent component

<Child fetchPetdata={this.fetchPetData} />

Upvotes: 2

Ekene
Ekene

Reputation: 125

A quick solution would be passing a function prop to the parent component which you'd call on update. So in your child function you have something like

submitHandler = event => {
  const { name, age, animal, breed } = this.state;

  db.doCreatePet(
    name,
    age,
    animal,
    breed,
    auth.currentUser.email.slice(0, -4)
  );
  this.setState({ ...INITIAL_STATE });
  event.preventDefault();
  this.props.reloadData(); // Add this
};

while in the parent component's render function you'd have

fetchData() {
  db
    .onceGetPets()
    .then(snapshot => this.setState(() => ({ pets: snapshot.val() })));
}

and in the render method you'd

render() {
  return (
    <Child reloadData={this.fecthData} ...props/>
  )
}

Upvotes: 1

Related Questions