【问题标题】:How can I change value of an item into array without modify others in React如何在不修改 React 中的其他项的情况下将项目的值更改为数组
【发布时间】:2016-10-23 17:31:13
【问题描述】:

我有一个简单的 todolist 结构进入组件的状态。这是一个数组,其中有两个字段称为“内容”,一个字段称为“完成”。我使用从父级传递给 TodoItem 子级的简单 onClick() 函数捕获行项的单击(如 React 教程建议):

  render() {
   const tthis = this;

   var myList = tthis.state.todos.map(function(todo,index){

      var myOnCLick = function(){
        var newTodo = {content: todo.content, done: !todo.done};
        tthis.state.todos[index] = newTodo;
        tthis.setState({});

      }
      return <Todo key={index} todo={todo} onClick={myOnCLick}/>
   })

   return (
     <ul className="list">
       { myList }
     </ul>
   )
 }

这段代码没有问题,但我不太喜欢。 我会找到一些好的解决方案来更改数组中单个项目的值。我在 React DOC 的 Immutability 助手中发现了这一点:

{$set: any} 完全替换目标。

在这个论坛的一个很好的答案中,我看到了一个例子:

this.setState({
  todos: update(this.state.todos, {1: {done: {$set: true}}})

但在我的情况下我不能使用 1。我有索引,它为我提供了待办事项列表中点击的待办事项的索引。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您可以通过以下方式翻转数组中列出的单个待办事项对象上的done 属性的值:

    flipDone(id) {
      let index = Number(id);
    
      this.setState({
        todos: [
          ...this.state.todos.slice(0, index),
          Object.assign({}, this.state.todos[index], {done: !this.state.todos[index].done}),
          ...this.state.todos.slice(index + 1)
        ]
      });
    }
    

    这是一个演示:http://codepen.io/PiotrBerebecki/pen/jrdwzB

    完整代码:

    class TodoList extends React.Component {
      constructor() {
        super();
        this.flipDone = this.flipDone.bind(this);
        this.state = {
          todos: [
            {content: 'Go shopping', done: false},
            {content: 'Walk the dog', done: false},
            {content: 'Wash the dishes', done: false},
            {content: 'Learn React', done: false}
          ]
        };
      }
    
      flipDone(id) {
        let index = Number(id);
    
        this.setState({
          todos: [
            ...this.state.todos.slice(0, index),
            Object.assign({}, this.state.todos[index], {done: !this.state.todos[index].done}),
            ...this.state.todos.slice(index + 1)
          ]
        });
      }
    
      render() {
        const myList = this.state.todos.map((todo, index) => {
          return (
            <Todo key={index} 
                  clickHandler={this.flipDone} 
                  content={todo.content}
                  done={todo.done}
                  id={index}
            />
          );
        })
    
        return (
          <ul className="list">
            {myList}
          </ul>
        );
      }
    }
    
    
    class Todo extends React.Component {
      constructor() {
        super();
        this.handleClick = this.handleClick.bind(this);
      }
    
      handleClick(event) {
        this.props.clickHandler(event.target.id);
      }
    
      render() {
        return (
          <li>
            <button onClick={this.handleClick}
                    id={this.props.id}>
              Click me
            </button> --- 
            {String(this.props.done)} --- 
            {this.props.content}      
          </li>
        );
      }
    }
    
    
    ReactDOM.render(
      <TodoList />,
      document.getElementById('app')
    );
    

    【讨论】:

    • 您希望我在上面添加任何内容还是回答您的问题?
    • 我从未使用过三点语法。您的解决方案效果很好,但列表调用中的所有 li 每次都会渲染 :)
    • 3 点语法被称为扩展运算符。例如:let cold = ['autumn', 'winter']; let warm = ['spring', 'summer']; console.log([...cold, ...warm]) => ['autumn', 'winter', 'spring', 'summer'] 更多信息:developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
    猜你喜欢
    • 1970-01-01
    • 2022-12-15
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 1970-01-01
    相关资源
    最近更新 更多