Skip to content

Commit

Permalink
fix: [Cascader] Fixed an error caused by untimely update of data in l…
Browse files Browse the repository at this point in the history
…oadingKeys (#1876)
  • Loading branch information
YyumeiZhang authored Oct 30, 2023
1 parent 8413c01 commit 574fd29
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
26 changes: 18 additions & 8 deletions packages/semi-foundation/cascader/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,11 @@ export interface CascaderAdapter extends DefaultAdapter<BasicCascaderProps, Basi
notifyListScroll: (e: any, panel: BasicScrollPanelProps) => void;
notifyOnExceed: (data: BasicEntity[]) => void;
toggleInputShow: (show: boolean, cb: () => void) => void;
updateFocusState: (focus: boolean) => void
updateFocusState: (focus: boolean) => void;
updateLoadingKeyRefValue: (keys: Set<string>) => void;
getLoadingKeyRefValue: () => Set<string>;
updateLoadedKeyRefValue: (keys: Set<string>) => void;
getLoadedKeyRefValue: () => Set<string>
}

export default class CascaderFoundation extends BaseFoundation<CascaderAdapter, BasicCascaderProps, BasicCascaderInnerData> {
Expand All @@ -242,6 +246,8 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
init() {
const isOpen = this.getProp('open') || this.getProp('defaultOpen');
this.collectOptions(true);
this._adapter.updateLoadingKeyRefValue(new Set());
this._adapter.updateLoadedKeyRefValue(new Set());

if (isOpen && !this._isDisabled()) {
this.open();
Expand Down Expand Up @@ -426,11 +432,11 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
const { changeOnSelect, onChangeWithObject, multiple } = this.getProps();
const {
activeKeys,
loadingKeys,
loading,
keyEntities: keyEntityState,
selectedKeys: selectedKeysState
} = this.getStates();
const loadingKeys = this._adapter.getLoadingKeyRefValue();
const filterable = this._isFilterable();
const loadingActive = [...activeKeys].filter(i => loadingKeys.has(i));

Expand Down Expand Up @@ -672,33 +678,37 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,

handleNodeLoad(item: BasicEntity | BasicData) {
const { data, key } = item;
const {
loadedKeys: prevLoadedKeys,
loadingKeys: prevLoadingKeys
} = this.getCopyFromState(['loadedKeys', 'loadingKeys']);
const prevLoadingKeys = cloneDeep(this._adapter.getLoadingKeyRefValue());
const prevLoadedKeys = cloneDeep(this._adapter.getLoadedKeyRefValue());
const newLoadedKeys = prevLoadedKeys.add(key);
const newLoadingKeys = new Set([...prevLoadingKeys]);
newLoadingKeys.delete(key);

// onLoad should trigger before internal setState to avoid `loadData` trigger twice.
this._adapter.notifyOnLoad(newLoadedKeys, data);
this._adapter.updateLoadingKeyRefValue(newLoadingKeys);
this._adapter.updateLoadedKeyRefValue(newLoadedKeys);
this._adapter.updateStates({
loadingKeys: newLoadingKeys,
loadedKeys: newLoadedKeys
});
}

notifyIfLoadData(item: BasicEntity | BasicData) {
const { data, key } = item;
this._adapter.updateStates({ loading: false });
if (!data.isLeaf && !data.children && this.getProp('loadData')) {
const { loadedKeys, loadingKeys } = this.getCopyFromState(['loadedKeys', 'loadingKeys']);
const loadedKeys = this._adapter.getLoadedKeyRefValue();
const loadingKeys = cloneDeep(this._adapter.getLoadingKeyRefValue());
if (loadedKeys.has(key) || loadingKeys.has(key)) {
return;
}
this._adapter.updateStates({ loading: true });
const { keyEntities } = this.getStates();
const optionPath = this.getItemPropPath(key, [], keyEntities);
this._adapter.updateStates({ loadingKeys: loadingKeys.add(key) });
const newLoadingKeys = loadingKeys.add(key);
this._adapter.updateLoadingKeyRefValue(newLoadingKeys);
this._adapter.updateStates({ loadingKeys: newLoadingKeys });
this._adapter.notifyLoadData(optionPath, this.handleNodeLoad.bind(this, item));
}
}
Expand Down
16 changes: 16 additions & 0 deletions packages/semi-ui/cascader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
clickOutsideHandler: any;
mergeType: string;
context: ContextValue;
loadingKeysRef: React.RefObject<Set<string> | null>;
loadedKeysRef: React.RefObject<Set<string> | null>;

constructor(props: CascaderProps) {
super(props);
Expand Down Expand Up @@ -269,6 +271,8 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
this.optionsRef = React.createRef();
this.clickOutsideHandler = null;
this.foundation = new CascaderFoundation(this.adapter);
this.loadingKeysRef = React.createRef();
this.loadedKeysRef = React.createRef();
}

get adapter(): CascaderAdapter {
Expand Down Expand Up @@ -389,6 +393,18 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
updateFocusState: (isFocus: boolean) => {
this.setState({ isFocus });
},
updateLoadingKeyRefValue: (keys: Set<string>) => {
(this.loadingKeysRef as any).current = keys;
},
getLoadingKeyRefValue: () => {
return this.loadingKeysRef.current;
},
updateLoadedKeyRefValue: (keys: Set<string>) => {
(this.loadedKeysRef as any).current = keys;
},
getLoadedKeyRefValue: () => {
return this.loadedKeysRef.current;
}
};
}

Expand Down

0 comments on commit 574fd29

Please sign in to comment.