Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Cascader 的异步加载数据,在快速触发大量节点加载(比如设置 showNext:'blur'),偶尔可能导致节点一直处于 loading 态 #1867

Closed
1 task done
YyumeiZhang opened this issue Oct 19, 2023 · 0 comments · Fixed by #1876

Comments

@YyumeiZhang
Copy link
Collaborator

Is there an existing issue for this?

  • I have searched the existing issues

Which Component

Cascader

Semi Version

2.44.0

Current Behavior

在同时触发多个节点的加载时,偶尔会出现节点内容已经加载完成,但是节点 还是处于 loading 的状态
img_v2_f230d684-7fb6-4f49-ad17-735c52bb188g

Expected Behavior

节点内容加载完成,节点状态显示正常

Steps To Reproduce

复现代码中设置了 showNext 为 hover ,粘贴复现demo 到官网编辑器,鼠标快速扫过第一列的选项,偶尔会出现某项数据一直在 loading 的状态

ReproducibleCode

export const CascaderOnLoad = () => {
  const myRef = useRef();
  const initialData = useMemo(() => {
    return (new Array(30)).fill(0).map((item, index) => ({
      label: `Node1-${index}`,
      value: `0-${index}`,
    }));
  }, []);
  const [data, setData] = useState(initialData);
  
  const updateTreeData = (list, value, children) => {
      return list.map(node => {
          if (node.value === value) {
              return { ...node, children };
          }
          if (node.children) {
              return { ...node, children: updateTreeData(node.children, value, children) };
          }
          return node;
      });
  };

  const onLoadData = selectedOpt => {
      const targetOpt = selectedOpt[selectedOpt.length - 1];
      const { label, value } = targetOpt;
      return new Promise(resolve => {
          if (targetOpt.children) {
              resolve();
              return;
          }

          setTimeout(() => {
              setData(origin =>
                  updateTreeData(origin, value, [
                      {
                          label: `${label} - 1`,
                          value: `${label}-1`,
                          isLeaf: selectedOpt.length > 1
                      },
                      {
                          label: `${label} - 2`,
                          value: `${label}-2`,
                          isLeaf: selectedOpt.length > 1
                      },
                  ]),
              );
              resolve();
          }, 1000);
      });
  };

  return (
    <>
      <Cascader
          showNext="hover"
          defaultOpen
          ref={myRef}
          style={{ width: 300 }}
          treeData={data}
          loadData={onLoadData}
          placeholder="Please select"
      />
    </>
  );
};

Environment

- OS:
- browser:

Anything else?

问题原因分析:在 Cascader 的 state 的 loadingKeys 管理了正在处于加载状态的 key 值,因为改变 loadingKeys 的值是基于上一次 loadingKeys的值, 问题可能和当前loadingKeys 值改变的逻辑相关。比如在 hanldeNodeLoad中
img_v2_cb559503-80f9-4873-9d6c-44920204056g

代码逻辑是每一次loadData成功之后会获取之前的loadingKeys数据,然后key数据删除掉后再重新赋值,那感觉有可能存在一种情况,假设两次loadData几乎同时触发,key分别是0,1,那两次loadingData都没返回之前,loadingKeys是[0, 1],接着key对应0的loadData返回了,然后执行handleNodeLoad逻辑,newLoadingKeys就是[1],然后进行一次updateStates,紧接着key为1的loadData返回了,同样执行handleNodeLoad逻辑,那么此时preLoadKeys有可能还是[0, 1],那么newLoadingKeys就是[0],然后执行updateStates,那这时候就会有问题,key为0这一项就一直是loading态了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant