我正在开发一个简单的“待办事项列表” react 应用程序(React.js 的新功能)。我已将项目添加到列表中,但删除项目会引发问题。在我的父 React 组件中,我有以下代码:
import ToDoEntries from './to_do_entries.jsx';
class ToDoList extends React.Component {
constructor(props) {
super(props);
this.state = { list: [] }
this.add = this.addItem.bind(this);
this.removeItem = this.removeItem.bind(this);
}
addItem(e) { //removed to avoid tl:dr }
render() {
return(
<form onSubmit={this.add}>
<input placeholder='Enter item' type='text' ref={(el) => {this._input = el;} }/>
<button>Add</button>
</form>
<ToDoEntries entries={this.state.list}
removeCallback={this.removeItem}
/>
);
}
}
我的 to_do_entries.jsx
组件:
class ToDoEntries extends React.Component {
constructor(props) {
super(props);
}
renderItems() {
const { entries, removeCallback } = this.props;
function createTasks(item) {
return <li key={item.key}>{item.text}</li>
}
var listItems = entries.map(function(item) {
return(<li onClick={removeCallback} key={item.key}>{item.text}</li>)
})
return listItems;
}
render() {
var todoEntries = this.renderItems();
return(
<ul>
{todoEntries}
</ul>
);
}
}
export default ToDoEntries;
运行这段代码带来:
Warning: setState(…): Cannot update during an existing state transition
问题:
为什么 to_do_entries.jsx
的 render 在添加项目时立即执行回调,即:
var listItems = entries.map(function(item) {
return(<li onClick={removeCallback(id)} key={item.key}>{item.text}</li>)
})
但是,添加 .bind(null, id)
删除回调即。 <li onClick={removeCallback.bind(null, id)} />
不是吗?
最佳答案
问题出在这部分:
onClick={removeCallback(id)}
我们需要向 onClick 传递一个函数,而不是值。当我们将 ()
与 functionName 一起使用时,这意味着您正在调用该方法并将其结果分配给 onClick
,这将创建一个无限循环 如果你在 removeCallback 中执行 setState
,因为这个循环:
render -> removeCallback() -> setState ->
^ |
| |
| |
-----------------------------------------
这就是您收到错误的原因。
检查代码段以了解 abc 和 abc()
之间的区别:
function abc(){
return 'Hello';
}
console.log('without () = ', abc); //will return the function
console.log('with () = ', abc()); //will return the function result (value)
Why it is working with
onClick={removeCallback.bind(null, id)}
?
因为绑定(bind)将创建一个新函数,并将该函数分配给点击事件,所以当您点击任何项目时,此处的removeCallback
将被调用,而不是自动调用。
根据 MDN Doc :
The bind() function creates a new bound function (BF). A BF is an exotic function object (a term from ECMAScript 2015) that wraps the original function object. Calling a BF generally results in the execution of its wrapped function.
检查 React DOC: Handling events in JSX .
查看此答案以获取有关绑定(bind)的更多详细信息: Use of the JavaScript 'bind' method
关于javascript - 警告 : setState(…): Cannot update during an existing state transition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45123805/