ReactJS:从子级和父级控制子级状态

Ada*_*ant 12 reactjs react-jsx

我有一个相当简单的问题,我不知道如何使用React的单向数据流来解决它.

假设您在父级中有一个显示模态的链接

在模态中,你有一个"X"来关闭它.

我知道我可以通过道具从父母改变模态的状态

// In the parent
<Modal display={this.state.showModal} />

// In the modal
<div className={this.props.display ? "show" : "hide"}>
  <a className="close">&times;</a>
  ...
</div>
Run Code Online (Sandbox Code Playgroud)

我知道如何关闭模态,但不是两者兼而有之.不确定如何保持父模式和子模式共享和控制的状态.

UPDATE

在尝试尽可能保持模块化时,我认为React方法是将开/关逻辑存储在模态变量中.

var ParentThing = React.createClass({
  ...
  render (
    <Modal /> // How can I call this.open in the modal from here?
  )
});

var Modal = React.createClass({
  setInitialState: function() {
    return {
      display: false
    }
  },
  close: function() {
    this.setState({ display: false });
  },
  open: function() {
    this.setState({ display: true });
  },
  render: function() {
    return (
      <div className={this.state.display ? "show" : "hide"}>
        <a className="close" onClick={this.close}>&times;</a>
      </div>
    )
  }
});
Run Code Online (Sandbox Code Playgroud)

我看到了这种方法,但它似乎比我在这里做的要多一点.Reactjs:如何从父级修改子状态或道具?

Mic*_*ley 16

在React中有两种方法可以处理这种事情:

  1. 使子项"受控制",就像带有valueonChange属性的表单输入一样,输入的所有者控制输入​​.
  2. 让孩子"不受控制",就像没有表格的表格输入一样value.

第二种选择似乎前期更快,但就像在React中管理表单输入的集合一样,使用完全受控组件的优势随着复杂性的构建以及在任何时间点完全描述UI的需求而变得明显.(请参阅FakeRainBrigand的这个优秀答案,如果你很好奇为什么受控组件在大多数情况下比不受控制的更好.)

但是,就像表单输入一样,没有理由不能控制不控制组件.如果用户通过一个displayonClose财产,像奥斯汀·格列柯的答案,你有一个控制模式,和家长完全决定何时显示或隐藏模式.

如果用户没有,您可以跳过使用属性,而是委托由模态组件上的公共方法管理的内部状态:

var ParentThing = React.createClass({
  ...
  render: function() {
    return <Modal ref="modal" />;
  },

  handleSomeClick: function() {
    this.refs.modal.open();
  }
});

var Modal = React.createClass({
  setInitialState: function() {
    return {
      display: false
    }
  },
  close: function() {
    this.setState({ display: false });
  },
  open: function() {
    this.setState({ display: true });
  },
  render: function() {
    return (
      <div className={this.state.display ? "show" : "hide"}>
        <a className="close" onClick={this.close}>&times;</a>
      </div>
    )
  }
});
Run Code Online (Sandbox Code Playgroud)

如果您喜欢受控Modal组件的想法,但又不想进行所有样板输入,您甚至可以实现类似valueLinkModal 的属性来简化此模式.

var ParentThing = React.createClass({
  ...
  mixins: [React.addons.LinkedStateMixin],

  getInitialState: function() {
    return { showModal: false };
  },

  render: function() {
    return <Modal displayLink={this.linkState("showModal")} />;
  },

  handleSomeClick: function() {
    this.setState({showModal: true});
  }
});

var Modal = React.createClass({
  close: function() {
    this.props.displayLink.requestChange(false);
  },

  render: function() {
    return (
      <div className={this.props.displayLink.value? "show" : "hide"}>
        <a className="close" onClick={this.close}>&times;</a>
      </div>
    )
  }
});
Run Code Online (Sandbox Code Playgroud)

(参见上创建与合作定制组件我的博客文章linkState/ valueLink获取更多信息.)

因此,现在您可以获得使用完全父控制的模态的好处,但是您已经删除了一部分样板,创建了一个将值设置为false并将其传递给模态的函数.


Aus*_*eco 7

您可以将回调作为prop传递给子组件:

// In the parent
<Modal display={this.state.showModal} onClose={this.closeModal} />

// In the modal
<div className={this.props.display ? "show" : "hide"}>
  <a className="close" onClick={this.props.onClose}>&times;</a>
  ...
</div>
Run Code Online (Sandbox Code Playgroud)

然后当您单击子项上的关闭按钮时,它将调用父项的功能