处理超过200个处于状态的复选框

问题描述 投票:1回答:1

我有一个表(父元素),该表可获取用户并将每一行呈现为其自己的组件。表中的行包含复选框。

目标是能够使用复选框并检索选中的复选框。

问题是,当我将函数传递给每一行(子组件)时,要触发将选中的复选框值添加到数组(由选定用户的ID组成),整个组件将被重新渲染,而且真的很滞后前端(显然)。我尝试为每个复选框创建引用,以仅在需要时才检索已选中的复选框-但您不能在循环中使用引用,对于这样的任务似乎不是一件好事。

我的问题是如何在一个表中处理大量复选框,如何将状态保存为已选中的复选框,或在父组件中触发某个函数时能够检索已选中的复选框?

const UserRow = ({checked, setChecked) => (
  // render fields
  // ...
  <Checkbox checked={checked} onChange={() => setChecked()} />
)

const ParentComponent = () => {
const [users, setUsers] = useState();
const [checkedCheckboxes, setCheckedCheckboxes] = useState([]);

useEffect(() => {
  // fetch users
  setUsers(fetchedUsers);
});

const rows = users.map(user => <UserRow
        key={id}
        name={user.name}
        email={user.email}
        checked={checkedCheckboxes.includes(id)}
        setChecked={setCheckedCheckboxes(checkedCheckboxes.concat(id)}
      />;

return (
  // render table
  {rows} // inset rows
)}
javascript reactjs
1个回答
1
投票

这里是一个优化的函数,它将在不重新渲染整个列表和使用useState中的列表的情况下切换项目。

import React, { useEffect, useState } from 'react';

const Parent = () => {
  //list is created and maintained in parent
  const [list, setList] = useState([
    { id: 1, val: true },
    { id: 2, val: true },
  ]);
  //toggle is id to indicate what item to toggle
  const [toggle, setToggle] = useState();
  useEffect(() => {
    if (toggle) {
      //setting toggle will not re render until
      //  function is finished so no infinite loop
      setToggle();
      //here we can toggle the item from the list
      setList(
        list.map(item =>
          item.id === toggle
            ? { ...item, val: !item.val }
            : item
        )
      );
    }
  }, [list, toggle]);
  //combining parent container with parent presentational
  //  for simplicity
  return (
    <div>
      {list.map(item => (
        <ItemContainer
          key={item.id}
          item={item}
          //pass setToggle as item clicked
          itemClicked={setToggle}
        />
      ))}
    </div>
  );
};
const ItemContainer = React.memo(function Item({
  item,
  itemClicked,
}) {
  //toggeling item with id 1 will not log
  //  for item with id 2
  console.log('in item render:', item.id);
  return (
    <pre onClick={() => itemClicked(item.id)}>
      {JSON.stringify(item, undefined, 2)}
    </pre>
  );
});

export default Parent;

Here是如何使用useReducer的示例。

© www.soinside.com 2019 - 2024. All rights reserved.