Closed ccpu closed 1 year ago
补充一个 jest 测试用例, 很奇怪, 跟 demo 表现并不一致
破案了, 在上述demo中, line: 44-48
{props.value?.map((item, index) => {
return (
<div key={index} style={{ marginBottom: 10, display: "flex" }}>
<RecursionField name={index} schema={schema.items} />
<button onClick={() => field.remove(index)}>Delete</button>
</div>
);
})}
这里的数组 key 给了个 index, 事件经过如下
packages/react/hooks/useAttach.ts
-> onMount/onUnmount
来修改的, 而 index
作为列表项的 key
这个 经典问题, 又在这里得到了验证: 第二条数据删除触发了 unMount
, 但第三条来补位并没有触发 onMount
这里就不展开了(packages/core/src/__test__/shared.ts
简单的手动执行, 所以在 jest 环境中没有复现
export const attach = <T extends { onMount: () => void }>(target: T): T => {
target.onMount()
return target
}
所以, demo 中的修复方案就是, 给列表项一个稳定的key
{props.value?.map((item, index) => {
return (
- <div key={index} style={{ marginBottom: 10, display: "flex" }}>
+ <div key={item.key} style={{ marginBottom: 10, display: "flex" }}>
<RecursionField name={index} schema={schema.items} />
<button onClick={() => field.remove(index)}>Delete</button>
</div>
);
})}
//...
field.setValue([
- { aa: { input: "1" } },
- { aa: { input: "2" } },
- { aa: { input: "3" } }
+ { aa: { input: "1" }, key: 1 },
+ { aa: { input: "2" }, key: 2 },
+ { aa: { input: "3" }, key: 3 }
]);
https://github.com/alibaba/formily/assets/18055018/c0ab25a4-7cb2-4c1d-84a9-d10226c8a0c7
以下是最初的测试代码和输出结果
综上, 这应该是使用的问题, 而不是 formily 的bug
另一个思路是, 因为这个attach也好, useAttach 也好, 只影响的 mounted/unmounted
这两个字段, 因此
在 packages/core/src/shared/internals.ts#patchFieldStates
方法中的 update 分支语句中, 强行修正 traget.mounted = true;traget.unmounted = false;
(可以根据是否之前位置是否删除再加一些优化判断)
但这只是 react 的会遇到的问题, 不是core的问题, 我个人是不赞同进行这样的修复, 而是尊重 react 的约定, 使用稳定的 key
Reproduction link
Steps to reproduce
What is expected?
After removing an item from the array, the mounted property of the remaining items should remain
true
.What is actually happening?
After removing an item from the array, the mounted property of the remaining items incorrectly becomes
false
.Package
@formily/core@2.2.29
This issue impacts the accurate tracking of the mounted state of array items, potentially leading to incorrect behaviours or rendering inconsistencies in complex forms.