score:7

Accepted answer

You may treat the checkbox as a dumb component, which means that it doesn't hold any internal states, but only receives data from outside via props and then render them. You can see the detailed definition of dumb components here.

Meanwhile, when the checkbox is clicked, such event will be handled by the component's parent, or event ancestors, this is called inverse data flow, which is described in Facebook's Thinking in React blog post.

Moreover, to decide which component should hold certain states, I find the following guidelines very useful:

Remember: React is all about one-way data flow down the component hierarchy. It may not be immediately clear which component should own what state. This is often the most challenging part for newcomers to understand, so follow these steps to figure it out:

For each piece of state in your application:

  • Identify every component that renders something based on that state.
  • Find a common owner component (a single component above all the components that need the state in the hierarchy).
  • Either the common owner or another component higher up in the hierarchy should own the state.
  • If you can't find a component where it makes sense to own the state, create a new component simply for holding the state and add it somewhere in the hierarchy above the common owner component.

The pseudo-code snippet:

const Checkbox = React.createClass({
  // Propagate the event to parents
  onClick(evt) {
    if (this.props.handleClick) {
      this.props.handleClick({checked: evt.target.value});
    }
  },

  render() {
    return (
      this.props.checked ? 
        <Input onClick={this.onClick} type="checkbox" label="Checkbox" checked></Input> : 
        <Input onClick={this.onClick} type="checkbox" label="Checkbox"></Input>
    );
  }
});

const Container = React.createClass({
  handleClick(evt) {
    // Change the container's state, which eventually changes the checkbox's view via props.
    this.setState({checked: evt.checked});
  },

  render() {
    return (
      <div><Checkbox checked={this.state.checked} handleClick={this.handleClick}></Checkbox></div>
    );
  }
});

score:3

You change it from only the parent.

class ParentComponent extends React.Component{
  handleChildCheck(){
    this.setState({
     childChecked: !this.state.childChecked
    })
  }
  render(){
    return(
      <ChildComponent checked={this.state.childChecked} handleCheck={this.handleChildCheck.bind(this)} />
    )
 }
}

Now if you wish to control the checked state from the <ChildComponent/> just call this.props.handleCheck() from the <ChildComponent/>

This way the controls will always be available within the <ChildComponent/> via this.props.handleCheck() within the <ParentComponent/> via this.handleChildCheck().


Related Query

More Query from same tag