How correctly update Parent component state in the Child component?

Hello,
I’m trying to rebuild the caculator with Reacat
Here is a part of my code
from App component I’m passing handleValue() to the Childe component Btns
And then when I click the button in Btns I want to update App state value

How correctly update App state value?
App component

class App extends React.Component {
  state = {
    value: null
  };

  handleValue(e) {
    e.preventDefault();
    this.setState({
      value: e.target.name
    });
  }

  render() {
    return (
      <div className="container">
        <div className="calculator">
          <Screen value={this.state.value} />
          <Btns value={this.handleValue} />
        </div>
      </div>
    );
  }
}

export default App;

Btns component

class Btns extends React.Component {
  handleClick = e => {
    e.preventDefault();
    this.props.value = e.target.name;
  };

  render() {
    return (
      <div className="keys">
        <button name="ac" onClick={this.handleClick} id="ac">
          AC
        </button>
        <button name="/" onClick={this.handleClick} id="divide">
          /
        </button>
        <button name="*" onClick={this.handleClick} id="multipl">
          *
        </button>
        <button name="7" onClick={this.handleClick} id="seven">
          7
        </button>
        <button name="8" onClick={this.handleClick} id="eight">
          8
        </button>
        <button name="9" onClick={this.handleClick} id="nine">
          9
        </button>
        <button name="-" onClick={this.handleClick} id="minus">
          -
        </button>
        <button name="4" onClick={this.handleClick} id="four">
          4
        </button>
        <button name="5" onClick={this.handleClick} id="five">
          5
        </button>
        <button name="6" onClick={this.handleClick} id="six">
          6
        </button>
        <button name="+" onClick={this.handleClick} id="plus">
          +
        </button>
        <button name="1" onClick={this.handleClick} id="one">
          1
        </button>
        <button name="2" onClick={this.handleClick} id="two">
          2
        </button>
        <button name="3" onClick={this.handleClick} id="three">
          3
        </button>
        <button name="=" onClick={this.handleClick} id="equal">
          =
        </button>
        <button name="0" onClick={this.handleClick} id="zero">
          0
        </button>
        <button name="." onClick={this.handleClick} id="dot">
          .
        </button>
      </div>
    );
  }
}

export default Btns;

Couple options,

One is manage state with redux and use reducers to update independent state stree. This way state is not tied to the components.

Two is pass down a function as a property to child from parent that sets the parent state

Unless Btns really needs to have access to its own state, I recommend changing it to a Stateless Function Component and then you would just pass the handleValue method down as a prop to Btns.

The render in App would become:

  render() {
    return (
      <div className="container">
        <div className="calculator">
          <Screen value={this.state.value} />
          <Btns buttonHandler={this.handleValue.bind(this)} />
        </div>
      </div>
    );
  }

And Btns would become:

const Btns = ({ buttonHandler }) => (
  <div className="keys">
    <button name="ac" onClick={buttonHandler} id="ac">
      AC
    </button>
    <button name="/" onClick={buttonHandler} id="divide">
      /
    </button>
    <button name="*" onClick={buttonHandler} id="multipl">
      *
    </button>
    <button name="7" onClick={buttonHandler} id="seven">
      7
    </button>
    <button name="8" onClick={buttonHandler} id="eight">
      8
    </button>
    <button name="9" onClick={buttonHandler} id="nine">
      9
    </button>
    <button name="-" onClick={buttonHandler} id="minus">
      -
    </button>
    <button name="4" onClick={buttonHandler} id="four">
      4
    </button>
    <button name="5" onClick={buttonHandler} id="five">
      5
    </button>
    <button name="6" onClick={buttonHandler} id="six">
      6
    </button>
    <button name="+" onClick={buttonHandler} id="plus">
      +
    </button>
    <button name="1" onClick={buttonHandler} id="one">
      1
    </button>
    <button name="2" onClick={buttonHandler} id="two">
      2
    </button>
    <button name="3" onClick={buttonHandler} id="three">
      3
    </button>
    <button name="=" onClick={buttonHandler} id="equal">
      =
    </button>
    <button name="0" onClick={buttonHandler} id="zero">
      0
    </button>
    <button name="." onClick={buttonHandler} id="dot">
      .
    </button>
  </div>
);
1 Like

Thanks a lot
it’s working :slight_smile: