Closed
Description
开发表单时多个表单值存在依赖关系时需要通过useEffect
更新表单值:
function CreateForm() {
const form = useFormInstance();
const formValueOfA = useWatch("a"); // initialValue: a
const formValueOfB = useWatch("b"); // initialValue: b
useEffect(() => {
if (a === "newValueA") {
form.setFieldValue("b", "newValueB");
}
}, [formValueOfA]);
useEffect(() => {
console.log([formValueOfA, formValueOfB]);
// [a, b]
// [newValueA, b] 非预期的中间状态
// [newValueA, newValueB]
}, [formValueOfA, formValueOfB]);
}
useEffect
更新依赖状态的问题在于当前render阶段获取的仍是旧值,需要在下次render才能获取到新值,这样就存在非预期的中间状态
这种场景不只在于同步表单状态,也可能是在useEffect中更新其他state
个人感觉这种场景也算是比较通用场景,可以通过一个hooks在当前render阶段获取预期值(仍然在useEffect阶段更新)
/**
* 根据依赖项和shouldUpdate判定条件返回状态的预期值
* 场景:主要用于useEffect更新form表单状态时,为了在当前render阶段获取到预期的表单值
* @param shouldUpdate 判定状态是否需要更新(依赖项未变化时不执行)
* @param next 返回预期值(需要更新的情况下返回)
* @param current 当前值(不需要更新的情况下返回)
* @param update 更新操作,一般是更新表单内容(需要更新时执行)
* @param deps 依赖项
*/
export function useExpect(
shouldUpdate: (previousDeps: DependencyList, newDeps: DependencyList) => boolean,
next: () => void,
current: () => any,
update: (v: any) => void,
deps: DependencyList,
) {
const depsRef = useRef<DependencyList>();
const previousDeps = depsRef.current;
const depsChanged = deps?.length !== previousDeps?.length || deps?.some((dep, i) => dep !== previousDeps?.[i]);
depsRef.current = deps;
const isShouldUpdate = depsChanged ? shouldUpdate(previousDeps, deps) : false;
const expectedValue = isShouldUpdate ? next() : current();
useEffect(() => {
if (isShouldUpdate) update(expectedValue);
});
return expectedValue;
}
Metadata
Metadata
Assignees
Labels
No labels