【问题标题】:react child component fails to render when calling parent callback with setstate使用 setstate 调用父回调时反应子组件无法呈现
【发布时间】:2017-11-10 08:03:48
【问题描述】:

我有一个父/子组件:

class Input extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: this.props.value};
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    // event is persisted, used to update local state
    // and then call parent onChange callback after local state update
    e.persist();
    this.setState(
      {value: e.target.value}, 
      () => this.props.onChange(e)
    );
  }

  render() {
    return (<input ... onChange={this.handleChange} />);
  }
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {modified: false};
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    const {name, value} = e.target;
    console.log(`${name}: ${value}`);
    // the two line execute fine, and everything works ok
    // but as soon as I add the bottom on, Input no longer updates!
    this.setState({modified: true});
  }

  render() {
    return (
      <Input ... onChange={this.handleChange} 
                 style={{backgroundColor: this.state.modified?"red":"blue"}}
      />
    );
  }
}

因此,一旦我对父组件执行 setState,子组件就不再正确呈现。为什么?是否与事件对象或子事件处理程序调用父事件处理程序有关?

【问题讨论】:

  • “不再正确渲染”是什么意思?它渲染还是不渲染?有什么改变吗?如果有,是什么?
  • 这是什么this.setState( {value: e.target.value}, () =&gt; this.props.onChange(e) );
  • @wesley6j 这会设置组件状态,并且当状态实际更新时 onChange 函数作为 prop 从父组件传递过来的被调用。请注意,setState 是异步的,它的第二个参数是回调函数,当应用状态更改时将调用该函数。
  • @BartekFryzowicz 谢谢。

标签: javascript reactjs components render setstate


【解决方案1】:

使用这个(?前后加空格):

style={{backgroundColor: this.state.modified ? "red" : "blue"}}

而不是这个:

style={{backgroundColor: this.state.modified?"red":"blue"}}

在此更改后,您的示例可以正常工作:

class Input extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: this.props.value};
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    // event is persisted, used to update local state
    // and then call parent onChange callback after local state update
    e.persist();
    this.setState(
      {value: e.target.value}, 
      () => this.props.onChange(e)
    );
  }

  render() {
    return (<input style={this.props.style}  onChange={this.handleChange} />);
  }
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {modified: false};
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    const {name, value} = e.target;
    console.log(`${name}: ${value}`);
    // the two line execute fine, and everything works ok
    // but as soon as I add the bottom on, Input no longer updates!
    this.setState({modified: true});
  }

  render() {
    return (
      <Input onChange={this.handleChange} 
                 style={{backgroundColor: this.state.modified ? "red":"blue"}}
      />
    );
  }
}

ReactDOM.render(
  <Page />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

【讨论】:

  • 不幸的是,它不起作用。在我的真实代码中,我实际上完全删除了样式属性。我还尝试将 this.props.onChange(e) 替换为自定义参数,例如 this.props.onChange({modified: this.state.modified}) 和在父 onChange 函数中我做了适当的更改,但问题仍然存在。在父 onChange 中调用 setState 会阻止子对象呈现。我的意思是,例如,当我输入文本时,修改不会反映出来。
  • 您是否从我的答案中运行了代码 sn-p?它似乎工作正常。
  • 为了清楚起见,您提供的示例有效,但不是我的真实代码,99% 相同,所以肯定有外部原因,但 1% 中没有任何内容(附加父母中的状态参数)可以解释这种行为。很奇怪。
  • 好吧,我的错,我发现了问题。我的子组件也有这个方法: componentWillReceiveProps(props) { this.setState({ value: props.value, modified: false });它引起了问题..我认为是因为无限渲染循环..谢谢!通过表明问题不在我认为的位置,我能够在其他地方寻找它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 2021-12-12
  • 2021-07-24
  • 1970-01-01
  • 2020-08-04
相关资源
最近更新 更多