javascript - 警告 : setState(…): Cannot update during an existing state transition

标签 javascript reactjs

我正在开发一个简单的“待办事项列表” 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/

相关文章:

javascript - 条件路由在 Switch 内部立即执行

reactjs - 在 React 和 Typescript 中只允许特定组件作为子组件

reactjs - 使用 React Error Boundaries 破坏了浏览器导航

javascript - 如何在爱彼迎 react 日期中选择小时/分钟

javascript - 如何从外部JS文件调用react js中的函数

javascript - React,这在 render() 和 componentDidMount() 中未定义

javascript - 如何根据下拉列表中的值在 Protractor 中创建 json 字符串

javascript - 检测用户对 DOM 的篡改

javascript - 无法捕获 Node.js 中的上下文

javascript - jQuery: array[i].children() 不是一个函数