如何在React组件上管理状态,该组件可以从父级或事件中的事件更改状态?

时间:2015-12-18 18:10:52

标签: reactjs

我试图创建一个自定义复选框组件(实际上是一个三态,但除了说我不只是使用INPUT之外,这是无关紧要的),而我&#39 ;我不知道如何让它能够改变"检查"点击自身和来自父母的价值集。

目前,我让它作为一个自给自足的组件工作,它接受一个onChange prop与它调用的处理程序回调,以便在点击后发送父组件的值。它使用状态来存储由显示器引用的检查。

如果它仅仅是检查的显示,从外部管理价值,我自然会使用道具。如果它只是一个自给自足的复选框组件,它取了一个初始值然后只响应了点击,我就像我一样使用状态,但我的问题是我希望它可以点击以打开和关闭,并允许父母也打开和关闭它。

我是React的初学者,以及" React的思维方式"所以我怀疑我只是接近这个错误。我得到的印象是,这样做的正确方法是将它作为一个仅显示组件,将点击向上传递给父级进行处理,然后从父级接收到值更改的道具更新,但是在我看来,这会使组件的可重用性降低。

那么我将如何从内部和父级来源更改复选框?

欢迎相关链接。

3 个答案:

答案 0 :(得分:7)

您可以将复选框视为哑组件,这意味着它不会保留任何内部状态,但只能通过 props 从外部接收数据然后渲染它们。您可以看到哑组件here的详细定义。

同时,当单击该复选框时,此类事件将由组件的父级或事件祖先处理,这称为逆数据流,在Facebook&#39中描述; s Thinking in React 博客文章。

此外,为了确定哪个组件应该具有某些状态,我发现以下指南非常有用:

  

请记住:React完全是关于组件层次结构中的单向数据流。可能不会立即清楚哪个组件应该拥有哪个状态。 对于新手来说,这通常是最具挑战性的部分,请按照以下步骤进行解决:

     

对于您申请中的每个州:

     
      
  • 根据该状态确定呈现某些内容的每个组件。
  •   
  • 查找公共所有者组件(在层次结构中需要状态的所有组件上方的单个组件)。
  •   
  • 公共所有者或层次结构中较高层的其他组件应拥有该状态。
  •   
  • 如果您无法找到拥有该状态的组件,请创建一个新组件,仅用于保存状态并将其添加到公共所有者组件上方的层次结构中。
  •   

伪代码段:

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>
    );
  }
});

答案 1 :(得分:3)

您只能从父级更改它。

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

现在,如果您希望通过<ChildComponent/>

this.props.handleCheck()拨打<ChildComponent/>来控制已选中状态

这样,<ChildComponent/>通过this.props.handleCheck() <ParentComponent/>通过this.handleChildCheck()flattenLong内的控件始终可用。

答案 2 :(得分:-2)

使用querySelectorAll查找您的组件。添加事件侦听器以监视更改。在更改时运行另一个querySelectorAll来查找子项并禁用或启用。这可能无法满足您的所有需求,但它会让您开始朝着正确的方向前进。这是普通的JavaScript,因此不需要其他库。

&#13;
&#13;
// Finds radios with class on-off and disables 'name-on' elements when
// 'name' is off.

function initOfOff() {
  var mains = document.querySelectorAll('.on-off');

  for (var i = 0; i < mains.length; i++) {
    var el = mains[i];
    var name = el.getAttribute('name');
    el.addEventListener('click', function() {
      var value = this.getAttribute('value');
      var children = document.querySelectorAll('.' + name + '-on');
      for (var i = 0; i < children.length; i++) {
        var child = children[i];
        child.checked = false;
        if (value == "off") {
          child.setAttribute('disabled', 'disabled');
        } else {
          child.removeAttribute('disabled');
        }
      }
    });
  }
}
initOfOff()
&#13;
<form name='myform'>power
  <input type='radio' value='on' class='on-off' name='power'>ON |
  <input type='radio' value='off' class='on-off' name='power'>Off
  <dir>lights

    <input type='radio' value='on' class='power-on' name='lights'>ON |
    <input type='radio' value='off' class='power-on' name='lights'>OFF
  </dir>
</form>
&#13;
&#13;
&#13;