简体   繁体   English

setState 对象数组而不改变对象顺序

[英]setState array of objects without changing objects order

In state, I have an array of list objects and would like to toggle the displayAddTaskForm.在 state 中,我有一个列表对象数组,并且想要切换 displayAddTaskForm。 Every time I set state, the list that gets clicked gets rearranged and moves to the front of the lists on the UI.每次我设置状态时,被点击的列表都会重新排列并移动到 UI 上列表的前面。 I believe I know why this is happening, just not sure of the solution.我相信我知道为什么会这样,只是不确定解决方案。 When I setState in toggleAddTaskForm, toggledList is first and then the other lists.当我在 toggleAddTaskForm 中设置状态时,toggledList 首先是其他列表。 How do I update the toggledList without changing the order of the lists.如何在不更改列表顺序的情况下更新 toggledList。 Here is the code.这是代码。

this.state = {
      lists: [
        {
          id: 1,
          header: "To Do",
          displayAddTaskForm: false,
        },
        {
          id: 2,
          header: "Working on It",
          displayAddTaskForm: false,
        },
        {
          id: 3,
          header: "Taken Care Of",
          displayAddTaskForm: false,
        }
      ],
      toggleAddTaskForm: (list) => {
        const toggledList = {...list, displayAddTaskForm: !list.displayAddTaskForm}
        const otherLists = this.state.lists.filter(l => l.id !== list.id)
        this.setState({
          lists: [toggledList, ...otherLists]
        })
      },
}

Putting function in the state is not a common thing.将函数放入状态并不是一件常见的事情。 I think you need to seperate that function from state.我认为您需要将该功能与状态分开。

You can easily toggle items using Array.map() and checking the clicked item id with the item id.您可以使用 Array.map() 轻松切换项目,并使用项目 ID 检查单击的项目 ID。 This will not change the order of items.这不会改变项目的顺序。

You can use the following code to toggle only one item:您可以使用以下代码仅切换一项:

class App extends Component {
  constructor() {
    super();
    this.state = {
      lists: [
        {
          id: 1,
          header: "To Do",
          displayAddTaskForm: false
        },
        {
          id: 2,
          header: "Working on It",
          displayAddTaskForm: false
        },
        {
          id: 3,
          header: "Taken Care Of",
          displayAddTaskForm: false
        }
      ]
    };
  }
  handleClick = id => {
    let newList = this.state.lists.map(item => {
      if (item.id === id) {
        return {
          ...item,
          displayAddTaskForm: !item.displayAddTaskForm
        };
      } else {
        return {
          ...item,
          displayAddTaskForm: false
        };
      }
    });

    this.setState({ lists: newList });
  };

  render() {
    return (
      <div>
        <ul>
          {this.state.lists.map(({ id, header, displayAddTaskForm }) => {
            return (
              <li key={id} onClick={() => this.handleClick(id)}>
                {header} - Toggle Value: {displayAddTaskForm ? "true" : "false"}
              </li>
            );
          })}
        </ul>
      </div>
    );
  }
}

Playground操场

Or if you want to be able to toggle every item, you can change the handleClick function like this:或者,如果您希望能够切换每个项目,您可以像这样更改 handleClick 函数:

  handleClick = id => {
    let newList = this.state.lists.map(item => {
      if (item.id === id) {
        return {
          ...item,
          displayAddTaskForm: !item.displayAddTaskForm
        };
      } else {
        return {
          ...item
        };
      }
    });

    this.setState({ lists: newList });
  };

Playground操场

You could find the index of the list, copy the lists, and insert the modified list into the new lists array at the same index.您可以找到列表的索引,复制列表,然后将修改后的列表插入到新列表数组的相同索引处。

toggleAddTaskForm: (list) => {
  const toggledList = {...list, displayAddTaskForm: !list.displayAddTaskForm}
  const newLists = [...this.state.lists];
  newLists[this.state.lists.indexOf(list)] = toggledList;
  this.setState({
    lists: newLists
  })
}

This might help.这可能会有所帮助。

 lists = [{ id: 1, header: "To Do", displayAddTaskForm: false, }, { id: 2, header: "Working on It", displayAddTaskForm: false, }, { id: 3, header: "Taken Care Of", displayAddTaskForm: false, }] const toggle = (list)=>{ const toggledList = { ...list, displayAddTaskForm: true } const indexOfList = lists.findIndex(({id}) => id === list.id) const newLists = [...lists] newLists[indexOfList] = toggledList setState({ lists: newLists }) } const setState = (o) => console.log(o) toggle(lists[1])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM