Reputation: 625
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
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
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