通过来自孩子的回调道具更新父母的状态(React.js)

时间:2015-06-19 15:27:26

标签: javascript reactjs

我使用 Form.jsx 组件 Page.jsx

<Form isValid={this.enableButton} isInvalid={this.disableButton}>
  <Input validation={{ presence: true }} />
</Form>

重点是:Form需要检查每个Input有效性以继续。为实现这一目标,我在Form.jsx

中执行此操作
// ...
allInputsAreValid: function () {
  return _.all(this.state.inputsValidation, function (inputsValidation) {
    return inputsValidation.error === false;
  });
}
// ...

然后,使用render的{​​{1}}方法:

Form.jsx

最后,方法if (this.allInputsAreValid()) { this.props.isValid(); } else { this.props.isInvalid(); } / enable(在 Form.jsx 上):

disableButton

在这些方法中更改状态,控制台会抛出错误:

  

未捕获错误:不变违规:setState(...):无法在现有状态转换期间更新(例如在// ... enableButton: function () { this.setState({ canSubmit: true }); }, disableButton: function () { this.setState({ canSubmit: false }); } //... 内)。渲染方法应该是道具和状态的纯函数。

为什么呢?怎么解决?

2 个答案:

答案 0 :(得分:0)

您需要将此逻辑移出render方法:

if (this.allInputsAreValid()) {
  this.props.isValid();
} else {
  this.props.isInvalid();
}

<强>更新

让我们修改您的<Input />组件以接受onChange道具。我不确定你是使用ES6类还是React.createClass,但我会在这里进入ES6课程。

class Input extends React.Component {
  render() {
    return <input type="text" onChange={this.props.onChange} />;
  }
}

然后修改 Form.jsx ,为输入提供onChange属性。

<Form isValid={this.enableButton} isInvalid={this.disableButton}>
  <Input
    validation={{ presence: true }}
    onChange={() => {
      if (this.allInputsAreValid()) {
        this.props.isValid();
      } else {
        this.props.isInvalid();
      }
    }}
  />
</Form>

答案 1 :(得分:0)

我假设&#34; page.jsx&#34;包含方法&#34; enableButton&#34;和&#34; disableButton&#34;。

在更新状态时,除了&#34; canSubmit&#34;?之外,您还有其他任何州的属性吗?如果你有其他州的财产以及&#34; canSubmit&#34;你正在通过

强迫他们变得不确定
  this.setState({
    canSubmit: true
  );

所以我假设有一个名为&#34; xyz&#34;与&#34; canSubmit&#34;一起存在国家财产。所以更新状态如下

this.setState({
    canSubmit: true,
    xyz:this.state.xyz
  );

或者更好,您尝试使用react update addon来更新状态。更多在这里找到https://facebook.github.io/react/docs/update.html

<强>更新

在page.jsx文件中尝试以下代码

  shouldComponentUpdate(object nextProps, object nextState){
     if(this.state.canSubmit==nextState.canSubmit){
        return false
     }
  }