【问题标题】:How to change an array element in state in a React如何在 React 中更改处于状态的数组元素
【发布时间】:2020-01-27 23:24:08
【问题描述】:

我正在尝试使用 handleToggle 方法更改数组的元素,但出现错误,我做错了什么,为什么我总是要在 React 中返回一个新数组?

子组件:

    function Todolist(props) {
      const todoItem = props.todos.map((todo, index) =>
        <ListItem key={todo.id} dense button>
          <ListItemIcon>
            <Checkbox checked={todo.completed} onChange={props.onChange(todo.id)} edge="start"/>
          </ListItemIcon>
          <ListItemText primary={todo.title} />
          <ListItemSecondaryAction>
            <IconButton edge="end" aria-label="comments"></IconButton>
          </ListItemSecondaryAction>
        </ListItem>
      )
      return (
        <div>
          {todoItem}
        </div>
      )
    }

父组件:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: '',
      todos: [
        {
          title: 'Learn React',
          id: Math.random(),
          completed: true
        }
      ]
    }
  };

  handleChange = (evt) => {
    this.setState({
      value: evt.target.value
    })
  };

  handleSubmit = (evt) => {
    evt.preventDefault();

    const todos = [...this.state.todos];

    todos.push({
      title: this.state.value,
      id: Math.random(),
      completed: false
    });

    this.setState(state => ({
      todos,
      value: ''
    }))
  };

  handleToggle = (id) => {
    const todos = [...this.state.todos];

    todos.map(todo => {
      if (todo.id === id) {
        return todo.completed = !todo.completed
      } else {
        return todo
      }
    });

    this.setState(state => ({
      todos
    }))
  };

  render() {
    return (
      <div className="App">
        <Grid className="Header" justify="center" container>
          <Grid item xs={11}>
            <h1 className="Title">My to-do react app</h1>
            <FormBox value={this.state.value} onSubmit={this.handleSubmit} onChange={this.handleChange}/>
          </Grid>
        </Grid>
        <TodoList todos={this.state.todos} onChange={this.handleToggle} />
      </div>
    );
  }
}

错误文本:

已超过最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React 限制了嵌套更新的数量以防止无限循环。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    你正在立即执行onChange

    onChange={props.onChange(todo.id)}
    

    将回调包装在arrow function

    onChange={() => props.onChange(todo.id)}
    

    您的 handleToggle 也没有正确更改值(变异),请尝试这样

    handleToggle = (id) => {
        const todos = [...this.state.todos];
    
        this.setState({ todos : todos.map(todo => ({
             ...todo, 
             completed : todo.id === id ? !todo.completed : todo.completed
         }) }))
      }
    

    【讨论】:

    • map 返回一个新数组,因此他还应该在将结果设置为 state 之前将结果收集到数组中。
    • 嘿伙计,我想他只想将具有指定 id 的待办事项更改为已完成
    • 错误是因为我忘记将返回的对象包装在( )中。是的(也错过了),我正在更新答案
    • 谢谢,我的错误是在箭头函数的回调中
    • 不客气!!您正在通过执行todo.completed = !todo.completed 来改变状态,请尝试改用spread 运算符。但是你的代码没有错。只是反模式
    猜你喜欢
    • 2017-12-28
    • 1970-01-01
    • 2020-10-21
    • 2017-08-09
    • 1970-01-01
    • 2018-03-21
    • 2023-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多