javascript - react componentdidupdate 引发无限循环

标签 javascript reactjs infinite-loop

我使用 onChange 触发对 elasticsearch 的 API 调用,以便我可以提示自动完成列表。 为了确保我的商店在重新渲染之前得到更新,我添加了 componentDidMount 这样我就不会落后一个滴答声。但是切入正题需要代码,所以:

constructor(props) {
  super(props)
  this.state = {
    inputValue: '',
    options: []
  };
  this.props = {
    inputValue: '',
    options: []
  };
  this._onChange = this._onChange.bind(this);
}

componentDidMount() {
  CodeStore.addChangeListener(this._onChange);
}

_onChange(event) {
  if (this.state.inputValue && !event) {
    var enteredChars = this.state.inputValue;
    console.log('NO EVENT!');
  } else if (event.target.value) {
    console.log('EVENT!');
    var enteredChars = event.target.value;
    this.setState({inputValue: enteredChars});
  }
  CodeService.nextCode(enteredChars);
}

如您所见,我添加了一些日志事件只是为了确保我的条件正常。我了解到 setState 会引发重新渲染,因此它在条件内,但并未停止循环。并且控制台日志确认条件切换。但是在我的条件中包含 setState 会阻止功能,我没有得到列表。

这是我的日志:

                        0
Home.jsx:48             EVENT!
Home.jsx:50             0
CodeService.js:27       request
CodeActions.js:10       dispatch
CodeStore.js:22         store
Home.jsx:43             1
Home.jsx:46             NO EVENT!
10OptionTemplate.jsx:15 render-list
CodeService.js:27       request
CodeActions.js:10       dispatch
CodeStore.js:22         store
Home.jsx:43             1
Home.jsx:46             NO EVENT!
10OptionTemplate.jsx:15 render-list
CodeService.js:27       request
CodeActions.js:10       dispatch
CodeStore.js:22         store
Home.jsx:43             1
Home.jsx:46             NO EVENT!

无限循环无论如何都不会影响性能。我认为是因为 componentWillUnmount 但必须避免大量的 API 调用。希望这足以提供任何证据。

最佳答案

看起来无限循环是由以下模式引起的:

  1. 用户类型输入
  2. _onChange 更新状态 + 触发存储操作
  3. 商店自行更新并发送更改事件
  4. 商店更改事件触发相同 _onChange 事件
  5. _onChange 不更新状态,但仍然触发存储操作
  6. 转到第 3 步并重复(无限期地)

修复步骤:

  • 为用户输入和商店更新制作不同的更改处理程序(正如@Janaka Stevens 已经建议的那样)
  • 将存储的数据置于状态
  • 用户输入不必处于状态(如果您的 React 代码未向输入字段提供值,它将以空值开头,并保留任何键入的内容)

那么你的代码可能看起来像这样:

constructor(props) {
  super(props)
  this.state = {
    options: []
  };
  // removed the this.props bit: props should not be updated inside component
  this._onChangeUser = this._onChangeUser.bind(this);
  this._onChangeStore = this._onChangeStore.bind(this);
}

componentDidMount() {
  CodeStore.addChangeListener(this._onChange);    // this is OK
}

_onChangeUser(event) {
  console.log('EVENT!');
  var enteredChars = event.target.value;
  CodeService.nextCode(enteredChars);
  // No need to update state here - go to sleep until store changes
}

_onChangeStore() {
  var newList = getListFromStore();  // your own function to get list from store
  this.setState({ options: newList});            // update state here
}

不确定“落后一步”是什么意思,或者可能是什么原因造成的,但清理无限循环是一个很好的起点;)

PS:以上代码仅为草图,可能有错别字。

关于javascript - react componentdidupdate 引发无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33525308/

相关文章:

javascript - 如何制作可缩放的粘性页脚

javascript - 使用 php/mysql/js 创建流程图/图表

javascript - 动态增加和缩小表格高度

javascript - 存储选项下拉列表中的状态,以便将其传递给父组件

reactjs - 更喜欢内联事件处理程序以避免代码中的间接性以提高人类可读性或使用处理程序函数?

javascript - 避免 React setState() 回调循环

javascript - pjax 请求一触发就将状态更改为已取消

javascript - JavaScript while 循环中的预自减运算符导致堆栈溢出

java - 在 AtomicInteger.addAndGet(int) 中使用无限循环

C# While 无限循环