fix(data-scope): avoid cyclic invocation of the same API (#4773)

* fix(data-scope): avoid cyclic invocation of the same API

* refactor: optimize potentially problematic code
This commit is contained in:
Zeke Zhang 2024-06-28 11:37:57 +08:00 committed by GitHub
parent 2141e6274d
commit bf4e100622
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 70 additions and 54 deletions

View File

@ -39,35 +39,41 @@ export function useParsedFilter({ filterOption }: { filterOption: any }) {
_run();
const run = _.debounce(_run, DEBOUNCE_WAIT);
reaction(() => {
// 这一步主要是为了使 reaction 能够收集到依赖
const flat = flatten(filterOption, {
breakOn({ key }) {
return key.startsWith('$') && key !== '$and' && key !== '$or';
},
transformValue(value) {
if (!isVariable(value)) {
return value;
}
const variableName = getVariableName(value);
const variable = findVariable(variableName);
reaction(
() => {
// 这一步主要是为了使 reaction 能够收集到依赖
const flat = flatten(filterOption, {
breakOn({ key }) {
return key.startsWith('$') && key !== '$and' && key !== '$or';
},
transformValue(value) {
if (!isVariable(value)) {
return value;
}
const variableName = getVariableName(value);
const variable = findVariable(variableName);
if (process.env.NODE_ENV !== 'production' && !variable) {
throw new Error(`useParsedFilter: can not find variable ${variableName}`);
}
if (process.env.NODE_ENV !== 'production' && !variable) {
throw new Error(`useParsedFilter: can not find variable ${variableName}`);
}
const result = getValuesByPath(
{
[variableName]: variable?.ctx || {},
},
getPath(value),
);
return result;
},
});
return flat;
}, run);
}, [JSON.stringify(filterOption), parseVariableLoading]);
const result = getValuesByPath(
{
[variableName]: variable?.ctx || {},
},
getPath(value),
);
return result;
},
});
return flat;
},
run,
{
equals: _.isEqual,
},
);
}, [JSON.stringify(filterOption)]);
return {
/** 数据范围的筛选参数 */

View File

@ -80,34 +80,40 @@ export default function useServiceOptions(props) {
_run();
const dispose = reaction(() => {
// 这一步主要是为了使 reaction 能够收集到依赖
const flat = flatten(filterFromSchema, {
breakOn({ key }) {
return key.startsWith('$') && key !== '$and' && key !== '$or';
},
transformValue(value) {
if (!isVariable(value)) {
return value;
}
const variableName = getVariableName(value);
const variable = findVariable(variableName);
const dispose = reaction(
() => {
// 这一步主要是为了使 reaction 能够收集到依赖
const flat = flatten(filterFromSchema, {
breakOn({ key }) {
return key.startsWith('$') && key !== '$and' && key !== '$or';
},
transformValue(value) {
if (!isVariable(value)) {
return value;
}
const variableName = getVariableName(value);
const variable = findVariable(variableName);
if (process.env.NODE_ENV !== 'production' && !variable) {
throw new Error(`useServiceOptions: can not find variable ${variableName}`);
}
if (process.env.NODE_ENV !== 'production' && !variable) {
throw new Error(`useServiceOptions: can not find variable ${variableName}`);
}
const result = getValuesByPath(
{
[variableName]: variable?.ctx || {},
},
getPath(value),
);
return result;
},
});
return flat;
}, run);
const result = getValuesByPath(
{
[variableName]: variable?.ctx || {},
},
getPath(value),
);
return result;
},
});
return flat;
},
run,
{
equals: _.isEqual,
},
);
return dispose;
}, [

View File

@ -144,6 +144,9 @@ const useParseDefaultValue = () => {
return value;
},
() => run({ forceUpdate: true }),
{
equals: _.isEqual,
},
);
return dispose;

View File

@ -15,6 +15,7 @@ import { reaction } from '@formily/reactive';
import { uid } from '@formily/shared';
import { getValuesByPath } from '@nocobase/utils/client';
import { ConfigProvider, Spin, theme } from 'antd';
import _ from 'lodash';
import React, { useEffect, useMemo } from 'react';
import { useActionContext } from '..';
import { useAttach, useComponent, useDesignable } from '../..';
@ -180,7 +181,7 @@ const WithForm = (props: WithFormProps) => {
return result;
},
getSubscriber(action, field, rule, variables, localVariables),
{ fireImmediately: true },
{ fireImmediately: true, equals: _.isEqual },
),
);
});