React.js |这两个功能之间的区别是什么?

时间:2020-06-03 08:35:58

标签: javascript reactjs function

我有一个复选框<input type='checkbox' onClick={ this.props.isTicked.bind(this,id)} /> 我还必须执行任务:

  state = {
    todos: [
      {
        id:1,
        title: 'Earn 10 lvl Faceit',
        completed: false
      },
      {
        id:2,
        title: 'Achieve 10 badges',
        completed: false
      }
    ]
  }

因此,复选框的ID等于其任务的ID。然后我想使“ isTicked”函数使完成的值相反。我也为每项任务都有风格(对与错,这是不同的)

            <div style ={this.TaskStyle()}>

                <p>
                    <input type='checkbox' onClick={ this.props.isTicked.bind(this,id)} />
                    {title}
                </p>
            </div>

TaskStyle:

    TaskStyle = () => {
        if (this.props.task_value.completed) {
            return {

                backgroundColor: 'darkgreen',
                fontFamily: 'Arial',
                padding:'10px'
            }
        }
        else {
            return {
                backgroundColor: 'gray',
                fontFamily: 'Arial',
                padding:'10px'
            }
        }

        }

现在,这是'isTicked'的工作版本:

    this.setState({todos: this.state.todos.map(todo => {
      if (todo.id === id) {
        todo.completed = !todo.completed
      }
      return todo
    })})

这是我的,我不知道为什么它不起作用....

  isTicked = (id) => {
    this.state.todos.forEach(todo => {
      if (todo.id === id) {
        todo.completed = !todo.completed
      }
      return todo
    });
  }

有人可以帮我吗?)

2 个答案:

答案 0 :(得分:1)

首先,在您的isTicked函数中,您没有像以前的方法那样设置状态。

第二,map返回一个新的Array,您将其设置为newState,而forEach则没有。实际上,这是两者之间的唯一区别。

现在,当您遍历forEach并直接更改状态时,React无法知道状态已更改,因此必须触发render函数。因此,在其他情况下您看不到更改。另一方面,在前一种情况下,当您通过setState修改状态时,React会依次重新渲染该组件,然后您会看到效果。

就这么简单:)

请勿直接修改状态例如,这不会重新呈现 组件:

// Wrong
this.state.comment = 'Hello';
// Instead, use setState():

// Correct
this.setState({comment: 'Hello'});

您可能想阅读以下内容:do-not-modify-state-directly

答案 1 :(得分:0)

您直接在此代码中操作状态:

isTicked = (id) => {
    this.state.todos.forEach(todo => {
      if (todo.id === id) {
        todo.completed = !todo.completed
      }
      return todo
    });
  }

可以规避Reacts状态管理,因此可以在代码中引入各种有害行为(错误)。第一个实现更好,但不是完美的,因为通过一些奇怪的巧合,您正在映射的状态可能会改变。最好使用setState回调语法:

this.setState(prevState => {
  const newState = prevState.todos.map(todo => {
    if (todo.id === id) {
      todo.completed = !todo.completed;
    }
    return todo;
  });

  return { ...prevState, newState };
});

这应该确保没有副作用发生。也许这个article对您有帮助。

此外,map返回一个具有映射值的新值,而forEach仅映射所有值,不返回任何值。