繁体   English   中英

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

[英]setState array of objects without changing objects order

在 state 中,我有一个列表对象数组,并且想要切换 displayAddTaskForm。 每次我设置状态时,被点击的列表都会重新排列并移动到 UI 上列表的前面。 我相信我知道为什么会这样,只是不确定解决方案。 当我在 toggleAddTaskForm 中设置状态时,toggledList 首先是其他列表。 如何在不更改列表顺序的情况下更新 toggledList。 这是代码。

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]
        })
      },
}

将函数放入状态并不是一件常见的事情。 我认为您需要将该功能与状态分开。

您可以使用 Array.map() 轻松切换项目,并使用项目 ID 检查单击的项目 ID。 这不会改变项目的顺序。

您可以使用以下代码仅切换一项:

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>
    );
  }
}

操场

或者,如果您希望能够切换每个项目,您可以像这样更改 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 });
  };

操场

您可以找到列表的索引,复制列表,然后将修改后的列表插入到新列表数组的相同索引处。

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

这可能会有所帮助。

 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