Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: Children onclick to change parent's state for re-rendering

I'm really new with react. I'm trying to get the parent to change page displayed depending on the states. I have a button in my sub-component that should send "true" or "false" to the parent component so it knows if to render it or not. I think it should be done with props like this:

this.state = {
   btnNewScreen: this.props.btnNewScreen //true or false
};

But im not getting it to work. Could you give any tips? Here is the full parent - child

parent - maindisplay.js

import React from 'react';
import Mainpage_Addscreen from '../components/subcomponents/mainpage-addscreen';
import Mainpage_Showscreens from '../components/subcomponents/mainpage-showscreens';
//
class MainDisplay extends React.Component {
    constructor() {
        super();
        this.state = {
            btnNewScreen: false //should be this.props.btnNewScreen?
        };
    }

    render() {
        var renderThis;
        if (!this.state.btnNewScreen) {
            renderThis =
                <div>
                    <Mainpage_Addscreen />
                    <Mainpage_Showscreens />
                </div>
        }
        else {
            //renderThis = <AddScreen />
            renderThis =
                <div>
                    <Mainpage_Addscreen />
                    <h3>Change to this when true (button click)</h3>
                </div>
        }
        return (
            <div>
                {renderThis}
            </div>
        );
      }
    }


    export default MainDisplay;

child - mainpage-addscreen.js

import React from 'react';

import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import Button from 'react-bootstrap/lib/Button';

class Mainpage_Addscreen extends React.Component {
    constructor() {
        super();
        this.state = {
            btnNewScreen: true
        };
        this.newScreen = this.newScreen.bind(this);
    }

    newScreen(e) {
        this.setState({ btnNewScreen: !this.state.btnNewScreen });
        console.log(this.state.btnNewScreen);
    }
    render() {
        var text = this.state.btnNewScreen ? 'Add new' : 'Screens';
        return (
            <div className="main_window col-sm-offset-1 col-sm-10">
                <h3 id="addscreens">Screens: </h3>
                <Button id="addScreen" className="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown" onClick={this.newScreen}><Glyphicon id="refresh_screens" glyph="plus" />&nbsp; {text}</Button>
            </div>
        );
    }
}


export default Mainpage_Addscreen;
like image 709
Jack M. Avatar asked Aug 11 '16 11:08

Jack M.


People also ask

Can you change parent component's state from the child component?

To update the parent state from the children component, either we can use additional dependencies like Redux or we can use this simple method of passing the state of the parent to the children and handling it accordingly.

Does React update all children components once the state of a parent has changed?

As a result, the child components only update when the parent component's state changes with one of those functions. Directly mutating the props object is not allowed since this won't trigger any changes, and React doesn't notice the changes.

Can a child update the state of a parent React?

We can set Parent State from Children Component in ReactJs using the following approach. We will actually set the state of a parent in the parent component itself, but the children will be responsible for setting. We will create a function in parent to set the state with the given input.

How do I change my state on click in React?

We have to set initial state value inside constructor function and set click event handler of the element upon which click, results in changing state. Then pass the function to the click handler and change the state of the component inside the function using setState.


2 Answers

What you probably need is a callback function, which your parent passes as a prop to your child, and that your child can then call.

Something like this:

// In parent
constructor() {
  ...
  this.onChildClicked = this.onChildClicked.bind(this);
}

onChildClicked() {
  this.setState({childWasClicked : True });
}

render() {
  ...
  return (
    <div>
      <Child onClicked={this.onChildClicked} />
    </div>
  )
}

// In child
render() {
  ...
  return (
    <div>
      <button onClick={this.props.onClicked} />
    </div>
  )
}

PS: I notice that you have a capitalized <Button> component. This is typically for components that you have defined yourself. Standard DOM elements take lowercase, e.g. <div>, <p> etc

like image 31
wintvelt Avatar answered Oct 22 '22 17:10

wintvelt


What you need to do is to pass a method from the parent to the child, That it can call when the button is clicked. This method that belongs to the parent will change the state.
In MainPage.js

changeButtonState(event) {
    this.setState({btnNewScreen: !this.state.btnNewScreen})
}

pass this method to your child component as

<Mainpage_Addscreen buttonClick={this.changeButtonState.bind(this)} />

and finally in the child component,

<Button ....   onClick={this.props.buttonClick} />
like image 170
Jeff P Chacko Avatar answered Oct 22 '22 16:10

Jeff P Chacko