[antd] In the onChange event of the table component using antd, the latest state of the parent component cannot be correctly obtained.

Let’s talk about the conclusion first

It is the closure that causes our state data to print the latest value after useEffect injects dependencies, while what is printed in the onTableChange event is the cached value when the closure was obtained.

Solution

Introduced useRefto save state, this ensures that every reference obtained is a new and unique latest value.

Code example:

// 编码模块
const Code = (props) => {
    
    
  const {
    
     searchParams, setSearchParams, selectedRowKeys, setSelectedRowKeys, tenantCode } = props;
  // 创建newSearchParamsRef的目的是为了避免闭包导致影响获取最新数据,闭包会缓存上一次的数据
  const newSearchParamsRef = useRef();
}
  useLayoutEffect(() => {
    
    
    codeFetchList(); // 更新table列表数据
    newSearchParamsRef.current = {
    
     ...searchParams };
  }, [searchParams, codeFetchList]);
// table onchange事件、排序
  const handleTableChange = (pagination: any, filters: any, sorter: any) => {
    
    
    const {
    
     order, field } = sorter;
    setSearchParams({
    
    
      ...(newSearchParamsRef.current || searchParams),
      pageNo: 1,
    });
  };
<Table
          sticky
          rowKey={
    
    (record: any) => record.id}
          loading={
    
    loading}
          columns={
    
    codeColumns}
          dataSource={
    
    codeList?.data?.rows}
          onChange={
    
    handleTableChange}
        />
)}

PS: Similar question (original link: https://blog.csdn.net/weixin_44634727/article/details/122666435):

When using antd's table component to render columns, the state of the parent component cannot be correctly obtained.

Problem Description

First of all, I used functional components (because of encapsulation, I wrote the following code in the parent component function)

Then in the parent component I defined a state to record the id of a certain function
Insert image description here

The initial value is 333 (this 333 will be useful later)
, but when displaying the component, I use the useEffect function to initiate a request to obtain the latest deptid of the backend, and then use setDeptid to reassign the deptid.
Insert image description here

Before reassigning the deptid, I have already rendered the columns of the table.
The following picture is a certain operation column in the columns.
Insert image description here

As shown above, the delete button is a deleteItem function
Insert image description here

As shown in the figure, the function execution will output the state of the parent component, but the output is 1, which is not the latest data.

Cause Analysis

究其原因发现原来,是我掉进了闭包陷阱当中
When rendering the table, I put the previous deptid into deleteItem, which formed a closure and cached the previous 333 in the memory. Then when you click the button again to trigger the deleteItem function, the value is taken out from the cache again. Then what is displayed is the previous value, and this problem does not exist in class components.

solution

As shown in the figure above, the solution is to use a useRef hook in the parent component to save the latest data. When needed, just console.log(countRef.current).
Insert image description here

Guess you like

Origin blog.csdn.net/hzxOnlineOk/article/details/132882979