Javascript react componentdidupdate引发无限循环
我使用Javascript react componentdidupdate引发无限循环,javascript,reactjs,infinite-loop,Javascript,Reactjs,Infinite Loop,我使用onChange触发对elasticsearch的API调用,以便提示自动完成列表。 为了确保我的商店在重新发布之前得到更新,我添加了componentDidMount,这样我就不会落后一步。但切入点需要代码,因此: 构造函数(道具){ 超级(道具) 此.state={ 输入值:“”, 选项:[] }; 此.props={ 输入值:“”, 选项:[] }; this.\u onChange=this.\u onChange.bind(this); } componentDidMount()
onChange
触发对elasticsearch的API调用,以便提示自动完成列表。
为了确保我的商店在重新发布之前得到更新,我添加了componentDidMount,这样我就不会落后一步。但切入点需要代码,因此:
构造函数(道具){
超级(道具)
此.state={
输入值:“”,
选项:[]
};
此.props={
输入值:“”,
选项:[]
};
this.\u onChange=this.\u onChange.bind(this);
}
componentDidMount(){
CodeStore.addChangeListener(this.\u onChange);
}
_onChange(事件){
if(this.state.inputValue&&!事件){
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(输入字符);
}
正如您所看到的,我添加了一些日志事件,只是为了确保我的状况正常。我了解到,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!
无限循环无论如何都不会影响性能。我认为,由于
组件将卸载,但必须避免大量的API调用。希望这些信息足以作为证据。看起来您正在对输入事件和存储侦听器使用onChange。它们需要单独的方法。看起来无限循环是由以下模式引起的:
用户类型输入
_onChange更新状态并触发要存储的操作
存储更新本身并发送更改事件
存储更改事件触发相同的更改事件
_onChange不更新状态,但仍会激发存储操作
转到步骤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
}
不确定“落后一个刻度”是什么意思,或者是什么导致了它,但清理无休止的循环是一个好的开始;)
注:以上代码仅为草图,可能有打字错误。这是正确的。即使有一个单独的循环,当我将函数添加到构造函数中时,它也会产生一个无限循环,但从构造函数中删除它会使我产生与以前相同的行为,我可以在日志中看到,我有一个10的数组,但视图渲染时没有。如果store listener使用_onChange和_onChange使用CodeService和CodeService触发器store和store触发器onChange和onChange触发器CodeService,那么我会将构造函数添加到问题中……好的,这很清楚:/infinity循环刚才提到,我有一个输出,这不是一个真正的解决方案。然后,我将搜索需要包含的内容,以便它处理重新渲染事件。谢谢!另外:最好避免在同一块/函数中执行this.setState()
之后的任何操作。由于setState()
触发重新呈现(即放弃当前块或函数),因此在同一块中的setState之后编写的任何语句(在您的情况下为'CodeService.nextCode(enteredChars);`)最多只能产生不可预测的结果。@wintvelt最好知道thx!但不幸的是,这并没有改变这种行为。您是否有任何关于组件didmount
外观的其他提示?如果需要更多信息,我将添加!哦,太好了,这真的帮了我的忙:)。稍后我将在这里公布结果。您是否有任何来源可以让您更深入地使用react?不客气。至于来源:是一个很好的来源。我特别推荐看这些视频。