kalecrush
kalecrush

Reputation: 71

Toggle boolean state between from parent component

Looking for a way to toggle a boolean state value in a child component from a method in the Parent component.

The Parent contains a method to open the contact form into view.

  handleContact() {
    this.setState({
      contactOpen: !this.state.contactOpen,
    });
  }

The ContactForm child component has a state for thankYou (boolean value) which gets set to true upon form submit.

The issue is when the Parent method to open the contact form is called after the form is already submitted, the Thank You message stays on the screen.

I have tried moving the thankYou state to the Parent and creating a showThankYou method in Parent and passing it to ContactForm child. The function does not seem to run and this way seems like it might be overly-complicated.

Is there a another way to update the boolean state in the child component from the handleContact method in the Parent?

Upvotes: 0

Views: 1065

Answers (2)

amirhaa
amirhaa

Reputation: 280

I suggest you to have one childComponent for your form and a childComponent/(just a jsx) for your thank you message and render both in the parent component like this:

// Parent
constructor(props) {
    super(props);

    this.state = {
        contactOpen: true,
        showThankU: false
    }
}

onSubmit(params) {
   // Do the submission process

   this.setState({showThankU: true, contactOpen: false}, () => {
       // in the callback use setTimout
       // to hide thank you box after desired seconds

       setTimeout(() => this.setState({showThankU: false), 10000);
   });
}

render() {
    return (
        <div>
            {/* if you would like to hide it after submit use this.state.contactOpen && */}
            {this.state.contactOpen && 
              <ContactsForm onSubmit={this.onSubmit.bind(this)}/>
            }

            {/* Whatever your thank you message (childComponet or just jsx) is: */}
            {this.state.showThankU && <ThankYouMessage {...props} />
        </div>
    );
}

if you would like to handle all in contactForm component you should pass a callback from parent to the child (contactForm) and change the state of showing the message or not and also pass that as another props to contactForm:

<ContactsForm 
    showMessage={this.state.showMessage}
    onSubmit={() => {
         this.setState({showMessage: true});
    }}
    {/* Other props */}
/>

And also keep in mind that when you want to pass a callback to child , you should be careful with this of JavaScript:

for that you could bind your methods like these:

// in constructor
this.myMethod = this.myMethod.bind(this)

// Or use ES6 and callback
<ChildComponent 
    myProp={() => this.myMethod()}
/>

// Or bind when passing to child
<ChildComponent
    myProp={this.myMethod.bind(this)}
/>

Upvotes: 1

Jos&#233; Santos
Jos&#233; Santos

Reputation: 66

    handleContact() {
    const contact = !this.state.contactOpen;
    this.setState({
      contactOpen: contact
    });
  }

Fix by Nicholas (https://stackoverflow.com/users/2836350/nicholas) (I think I already tried this approach and didn't work for me, that's why i use the one from above):

handleContact=()=> this.setState(prevState=>({contactOpen: !prevState.contactOpen}))

Upvotes: 0

Related Questions