fix: 优化多个loading时的性能 (#5804)

This commit is contained in:
meerkat 2022-11-28 18:11:39 +08:00 committed by GitHub
parent 3783d5c64f
commit d10c5aa322
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -42,7 +42,7 @@ const SpinnerSharedStore = types
.volatile(self => {
return {
// 保存所有可以进入 loading 状态props.show = true的 Spinner 的父级容器
spinnerContainers: observable.set([] as HTMLElement[], {
spinningContainers: observable.set([] as HTMLElement[], {
deep: false
})
};
@ -50,14 +50,14 @@ const SpinnerSharedStore = types
.actions(self => {
return {
push: (spinnerContainer: HTMLElement) => {
if (self.spinnerContainers.has(spinnerContainer)) {
if (self.spinningContainers.has(spinnerContainer)) {
return;
}
self.spinnerContainers.add(spinnerContainer);
self.spinningContainers.add(spinnerContainer);
},
remove: (spinnerContainer: HTMLElement) => {
if (self.spinnerContainers.has(spinnerContainer)) {
self.spinnerContainers.delete(spinnerContainer);
if (self.spinningContainers.has(spinnerContainer)) {
self.spinningContainers.delete(spinnerContainer);
}
},
/**
@ -66,15 +66,15 @@ const SpinnerSharedStore = types
* @returns {boolean} loading
*/
checkLoading: (spinnerContainerWillCheck: HTMLElement | null) => {
if (self.spinnerContainers.has(spinnerContainerWillCheck)) {
if (!self.spinnerContainers.size) {
if (self.spinningContainers.has(spinnerContainerWillCheck)) {
if (!self.spinningContainers.size) {
return false;
}
let loading = true;
// 检查缓存的容器中是否有当前容器的父级元素
self.spinnerContainers.forEach(container => {
self.spinningContainers.forEach(container => {
if (
container.contains(spinnerContainerWillCheck) &&
container !== spinnerContainerWillCheck
@ -95,7 +95,7 @@ const store = SpinnerSharedStore.create({});
export class Spinner extends React.Component<
SpinnerProps,
{spinning: boolean; showMark: boolean}
{spinning: boolean; showMarker: boolean}
> {
static defaultProps = {
show: true,
@ -111,40 +111,41 @@ export class Spinner extends React.Component<
state = {
spinning: false,
showMark: true
showMarker: true
};
parent: HTMLElement | null = null;
/**
* same parent node spinner show true
* spinning; push: + 1 ; remove: -1;
* > 0 : spinning = checkLoading
* = 0 : spinning = false; cannot remove
* loading
*/
count: number = 0;
loadingTriggered: boolean = false;
spinnerRef = (dom: HTMLElement) => {
if (dom) {
this.parent = dom.parentNode as HTMLElement;
this.setState({
showMark: false
});
}
};
componentDidUpdate() {
if (this.parent) {
if (this.props.show) {
this.count++;
this.loadingTriggered = true;
store.push(this.parent);
} else if (this.state.spinning && this.count > 0) {
} else if (this.state.spinning && this.loadingTriggered) {
this.loadingTriggered = false;
store.remove(this.parent);
this.count--;
}
}
}
componentDidMount() {
if (this.parent && this.state.showMarker) {
this.setState({showMarker: false});
}
}
componentWillUnmount() {
// 卸载 reaction
this.loadingChecker();
@ -153,13 +154,13 @@ export class Spinner extends React.Component<
}
/**
* spinnerContainers
* spinningContainers
*/
loadingChecker = reaction(
() => store.spinnerContainers.size,
() => store.spinningContainers.size,
() => {
this.setState({
spinning: store.checkLoading(this.parent) && this.count > 0
spinning: store.checkLoading(this.parent) && this.loadingTriggered
});
}
);
@ -181,7 +182,7 @@ export class Spinner extends React.Component<
return (
<>
{this.state.showMark && (
{this.state.showMarker && (
<span className={cx('Spinner-mark')} ref={this.spinnerRef as any} />
)}
<Transition