【问题标题】:React Handling Events反应处理事件
【发布时间】:2017-08-22 16:07:11
【问题描述】:

简单的待办事项列表。我想添加一个删除功能但出现错误:

proxyConsole.js:56 警告:setState(...):在现有状态转换期间无法更新(例如在 render 或其他组件的构造函数中)。渲染方法应该是 props 和 state 的纯函数;构造函数副作用是一种反模式,但可以移至componentWillMount

当我试图掌握它时,我可能会弄乱绑定。

class App extends Component {
  constructor(props) {
    super(props);
     this.onDelete = this.onDelete.bind(this);
     this.state = {
     todos: ['wash up', 'eat some cheese', 'take a nap'],
  };
}

render() {
  var todos = this.state.todos;
  todos = todos.map(function(item, index){
   return(
     <TodoItem item={item} key={index} onDelete={this.onDelete}/>
  )
}.bind(this));

return (
  <div className="App">
    <ul>
      {todos}
    </ul>
  </div>
);
}

onDelete(item){
    var updatedTodos = this.state.todos.filter(function(val, index){
      return item !== val;
    });
    this.setState({
      todos:updatedTodos
    });
  }
}

class TodoItem extends Component {
  constructor(props) {
    super(props);
    this.handleDelete = this.handleDelete(this);

  }

  render(){
    return(
      <li>
        <div className="todo-item">
          <span className="item-name">{this.props.item}</span>
          <span className="item-delete" onClick={this.handleDelete}> x</span>
        </div>
      </li>
    );
  }

handleDelete(){
    this.props.onDelete(this.props.item);
  }
}

【问题讨论】:

  • 您在定义的两个类之外都有 onDelete 函数有什么原因吗?
  • 格式问题。它在应用程序中,就在 render() 之后
  • 啊你知道它可能是这样的:this.handleDelete = this.handleDelete(this);将其更改为 this.handleDelete = this.handleDelete.bind(this);我认为它会在构建 TodoItem 类时立即执行该方法。

标签: javascript reactjs


【解决方案1】:

我认为您正在子组件的构造函数中调用 handleDelete 处理程序。应该是:

this.handleDelete = this.handleDelete.bind(this);

class App extends React.Component {
  constructor(props) {
    super(props);
    this.onDelete = this.onDelete.bind(this);
    this.state = {
      todos: ["wash up", "eat some cheese", "take a nap"]
    };
  }

  render() {
    var todos = this.state.todos;
    todos = todos.map(
      function(item, index) {
        return <TodoItem item={item} key={index} onDelete={this.onDelete} />;
      }.bind(this)
    );

    return (
      <div className="App">
        <ul>
          {todos}
        </ul>
      </div>
    );
  }

  onDelete(item) {
    var updatedTodos = this.state.todos.filter(function(val, index) {
      return item !== val;
    });
    this.setState({
      todos: updatedTodos
    });
  }
}

class TodoItem extends React.Component {
  constructor(props) {
    super(props);
    this.handleDelete = this.handleDelete.bind(this);
  }

  render() {
    return (
      <li>
        <div className="todo-item">
          <span className="item-name">{this.props.item}</span>
          <span className="item-delete" onClick={this.handleDelete}> x</span>
        </div>
      </li>
    );
  }

  handleDelete() {
    this.props.onDelete(this.props.item);
  }
}

ReactDOM.render(<App />, document.getElementById("app"));
<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="app"/>

【讨论】:

  • 这很好。就个人而言,我认为创建一个新函数会更好,将其命名为“renderToDoList()”,并将用于映射 todos 的逻辑放在那里,而不是在 render 方法中进行。在 jsx 主体内部,如果您这样做,您会调用 {this.renderToDoList()}。不过好东西,它有效。
  • @DanielZuzevich,是的,我们也可以这样做。我只是想强调 OP 的问题。 :-)。所以我并没有对原代码做太多改动。
猜你喜欢
  • 2015-07-22
  • 2021-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 2021-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多