繁体   English   中英

更新字段时组件不显示更新的数据?

[英]Component not displaying updated data when field is updated?

我有一个表,其中填充了来自对象数组的数据。

这些数据是通过 websockets 收集的。 套接字侦听 3 个不同的事件,并根据事件对数组执行以下操作之一:

  1. 用户可以添加一个条目 - ✅ 完全有效
  2. 用户可以修改条目 - 问题
  3. 用户可以删除一个条目 - ✅ 完全有效

这是代码:

interface TableEntry {
  address: string;
  amount: string;
  children?: React.ReactNode;
}

export const TableComponent: FC = () => {
  const socket = useContext(SocketContext);
  const [entriesArray, setEntriesArray] = useState<TableEntry[]>([]);
  const { globalAddress } =
    useContext(UserDetailsContext);

  useEffect(() => {
    socket.on("end", (data) => {
      setEntriesArray([]);
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    var tempEntries = entriesArray;
    socket.on("entry", (data) => {
      tempEntries.push({ address: data[0], amount: data[1] });
      setEntriesArray(tempEntries);
      tempEntries = [];
    });
    return function () {
      socket.off("entry");
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  //Update an entry on request from a user
  useEffect(() => {
    var tempEntries = entriesArray;
    socket.on("updateEntry", (data) => {
      const findFunc = (element: TableEntry) => element.address == data[0];
      const index = tempEntries.findIndex(findFunc);

      tempEntries[index].address = "updated address";

      setEntriesArray(tempEntries);
      tempEntries = [];
    });
    return function () {
      socket.off("updateEntry");
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

return (
    <>
      <Box>
        <Box
          w="427px"
          h="450px"
          top={"72px"}
          right={"60px"}
          bg={"rgba(255, 255, 255, 0.08)"}
          position={"absolute"}
          borderRadius="21"
          overflow="hidden"
        >
          <TableContainer>
            <Table variant="simple">
              <Thead>
                <Tr>
                  <Th fontFamily={"Orbitron"}>Address</Th>
                  <Th fontFamily={"Orbitron"}>Amount</Th>
                </Tr>
              </Thead>
              <Tbody>
                {entriesArray?.map((entry) => {
                  return entry.address == globalAddress ? (
                    <Tr key={entry.address} bg={"rgba(255, 255, 255, 0.05)"}>
                      <Td fontFamily={"Orbitron"}>{shorten(entry.address)}</Td>
                      <Td fontFamily={"Orbitron"}>{entry.amount}</Td>
                    </Tr>
                  ) : (
                    <Tr key={entry.address}>
                      <Td fontFamily={"Orbitron"}>{shorten(entry.address)}</Td>
                      <Td fontFamily={"Orbitron"}>{entry.amount}</Td>
                    </Tr>
                  );
                })}
              </Tbody>
            </Table>
          </TableContainer>
        </Box>
      </Box>
    </>
  );
};

数据更新,但未显示在表格中 - 如何确保表格中的数据反映更新?

我假设因为我正在更改 entryArray 的entriesArray强制重新渲染 - 但情况似乎并非如此?

React 的 state 是不可变的,所以你不能直接更新数组项。 您需要同时使用map{...element}来克隆和更新该数组项。

useEffect(() => {
  socket.on("updateEntry", (data) => {
    const tempEntries = entriesArray.map((element: TableEntry) =>
      element.address == data[0]
        ? { ...element, address: "updated address" } //update the found element
        : element //keep the original element
    );

    setEntriesArray(tempEntries);
    tempEntries = [];
  });
  return function () {
    socket.off("updateEntry");
  };
  // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

请注意,您也可以在更新任何元素之前使用[...entriesArray]cloneDeep类的扩展运算符克隆整个数组,但这并不可取,因为这意味着您想要渲染整个数组(即使您想要渲染仅更新元素)如果你有一个巨大的数组,它会影响性能。

您正在改变原始的 state 阵列。 当你输入var tempEntries = entriesArray; 您刚刚将 tempEntries 指向相同的 state object 用于创建新的 object 在您的情况下它是一个数组,您可以这样做

let tempEntries = [...entriesArray];

暂无
暂无

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

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