更新对象数组的状态时,React 不会重新渲染

时间:2021-01-20 08:57:05

标签: javascript reactjs typescript use-state

我的表没有重新渲染,即使状态更新实际上改变了数组,但表上的重新渲染没有发生。

我的初始状态如下:

  const [data, setData] = React.useState<Pendaftar[]>([]);
  
  React.useEffect(() => {
    setData(dataPendaftar);
  }, []);

这是我对接口的实现:

export interface Pendaftar {
  nim: string;
  name: string;
  divisi: string;
  lulus: boolean;
}

我的处理程序完成如下:

  const onSelectChange = (nim: string, i: number) => (
    e: React.ChangeEvent<HTMLSelectElement>,
  ) => {
    console.log(nim, i, e.target.value);
    const newData = [...data];
    newData[i] = { ...newData[i], lulus: e.target.value === 'true' };
    setData([...newData]);
  };

我在这里要做的是在触发 onSelectChange 时重新渲染表体。 我的桌子(使用 Chakra UI):

  return (
    <>
      <Table variant="simple">
        <Thead>
          <Tr>
            <Th>nama</Th>
            <Th>divisi</Th>
            <Th>lulus seleksi form?</Th>
          </Tr>
        </Thead>
        <Tbody>
          {dataPendaftar.map((d, i) => (
            <Tr key={d.nim}>
              <Td>
                {d.name} ({d.nim}) ({d.lulus ? 'y' : 'g'})
              </Td>
              <Td>{d.divisi}</Td>
              <Td>
                <Select
                  defaultValue={'option1'}
                  onChange={onSelectChange(d.nim, i)}
                >
                  <option value="option1" disabled>
                    Pilih
                  </option>
                  <option value="true">Ya</option>
                  <option value="false">Tidak</option>
                </Select>
              </Td>
            </Tr>
          ))}
        </Tbody>
      </Table>
    </>
  );

我在控制台上进行了日志记录,对象数组已按原样更改,但表 (({d.lulus ? 'y' : 'g'})) 一侧的重新渲染不会发生。更新状态的情况有没有处理不当?任何有关此事的解释都会对我有所帮助。

编辑 1:尝试了所有发布的解决方案,但仍然无效。

2 个答案:

答案 0 :(得分:2)

onChange={onSelectChange(d.nim, i)替换onChange={() => onSelectChange(d.nim, i)

现在你在每次渲染时调用一次函数,而不是在值实际改变时

答案 1 :(得分:0)

这是您需要做的:

const onSelectChange = (nim: string, i: number) => (
  e: React.ChangeEvent<HTMLSelectElement>
) => {
  setData(data => data.map((item, index)=> {
    if(index === i){
      return {
        ...item,
        lulus: e.target.value === "true",
      };
    }
    return item;
  }));
};
<Select defaultValue={"option1"} onChange={e => onSelectChange(d.nim, i)}>
  <option value="option1" disabled>
    Pilih
  </option>
  <option value="true">Ya</option>
  <option value="false">Tidak</option>
</Select>;