Bläddra i källkod

fix: [Tree] fix the expansion of the controlled tree is unsuccessful … (#1137)

* fix: [Tree] fix the expansion of the controlled tree is unsuccessful when loading data remotely

* fix: Perfect conditions
YyumeiZhang 3 år sedan
förälder
incheckning
27b7ccb02c
2 ändrade filer med 90 tillägg och 1 borttagningar
  1. 74 0
      packages/semi-ui/tree/_story/tree.stories.js
  2. 16 1
      packages/semi-ui/tree/index.tsx

+ 74 - 0
packages/semi-ui/tree/_story/tree.stories.js

@@ -2543,6 +2543,80 @@ class DemoV extends React.Component {
     }
 }
 
+export const issue1124 = () => {
+  const [v, setV] = useState(['1']);
+  const initialData = [ 
+      {
+          label: 'Expand to load',
+          value: '0',
+          key: '0',
+      },
+      {
+          label: 'Expand to load',
+          value: '1',
+          key: '1',
+      },
+      {
+          label: 'Leaf Node',
+          value: '2',
+          key: '2',
+          isLeaf: true,
+      },
+  ];
+  const [treeData, setTreeData] = useState(initialData);
+
+  function updateTreeData(list, key, children) {
+      return list.map(node => {
+          if (node.key === key) {
+              return { ...node, children };
+          }
+          if (node.children) {
+              return { ...node, children: updateTreeData(node.children, key, children) };
+          }
+          return node;
+      });
+  }
+
+  const onChange = (value) => {
+    setV(value);
+  }
+
+  function onLoadData({ key, children }) {
+      return new Promise(resolve => {
+          if (children) {
+              resolve();
+              return;
+          }
+          setTimeout(() => {
+              setTreeData(origin =>
+                  updateTreeData(origin, key, [
+                      {
+                          label: `Child Node${key}-0`,
+                          key: `${key}-0`,
+                          value: `${key}-0`,
+                      },
+                      {
+                          label: `Child Node${key}-1`,
+                          key: `${key}-1`,
+                          value: `${key}-1`,
+                      },
+                  ]),
+              );
+              resolve();
+          }, 1000);
+      });
+  }
+  return (
+      <Tree 
+          onChange={onChange}
+          loadData={onLoadData}
+          treeData={[...treeData]}
+          value={v}
+          multiple
+      />
+  );
+}
+
 export const virtualizeTree = () => <DemoV />;
 
 virtualizeTree.story = {

+ 16 - 1
packages/semi-ui/tree/index.tsx

@@ -281,13 +281,28 @@ class Tree extends BaseComponent<TreeProps, TreeState> {
                     props.multiple,
                     valueEntities
                 );
-            } else if ((!prevProps || (!isExpandControlled && dataUpdated)) && props.value) {
+            } else if (!prevProps && props.value) {
                 newState.expandedKeys = calcExpandedKeysForValues(
                     props.value,
                     keyEntities,
                     props.multiple,
                     valueEntities
                 );
+            } else if ((!isExpandControlled && dataUpdated) && props.value) {
+                // 当 treeData 已经设置具体的值,并且设置了 props.loadData ,则认为 treeData 的更新是因为 loadData 导致的
+                // 如果是因为 loadData 导致 treeData改变, 此时在这里重新计算 key 会导致为未选中的展开项目被收起
+                // 所以此时不需要重新计算 expandedKeys,因为在点击展开按钮时候已经把被展开的项添加到 expandedKeys 中
+                // When treeData has a specific value and props.loadData is set, it is considered that the update of treeData is caused by loadData
+                // If the treeData is changed because of loadData, recalculating the key here will cause the unselected expanded items to be collapsed
+                // So there is no need to recalculate expandedKeys at this time, because the expanded item has been added to expandedKeys when the expand button is clicked
+                if (!(prevState.treeData && prevState.treeData?.length > 0 && props.loadData)) {
+                    newState.expandedKeys = calcExpandedKeysForValues(
+                        props.value,
+                        keyEntities,
+                        props.multiple,
+                        valueEntities
+                    );
+                }
             }
 
             if (!newState.expandedKeys) {