Skip to content

Commit f39eb44

Browse files
authored
fix: 修复相同 name 的 Field 卸载同时加载 useWatch 返回为 undefined (#451)
* fix: 修复卸载同时加载 watch 返回为 undefined * feat: 修改逻辑 * feat: 修改逻辑 * feat: 恢复 * feat: 恢复 * feat: coverage * feat: test * feat: key
1 parent 4fab291 commit f39eb44

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

src/useWatch.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { getNamePath, getValue } from './utils/valueUtil';
99
type ReturnPromise<T> = T extends Promise<infer ValueType> ? ValueType : never;
1010
type GetGeneric<TForm extends FormInstance> = ReturnPromise<ReturnType<TForm['validateFields']>>;
1111

12-
function stringify(value: any) {
12+
export function stringify(value: any) {
1313
try {
1414
return JSON.stringify(value);
1515
} catch (err) {
@@ -97,6 +97,7 @@ function useWatch(dependencies: NamePath = [], form?: FormInstance) {
9797

9898
// Compare stringify in case it's nest object
9999
if (valueStrRef.current !== nextValueStr) {
100+
valueStrRef.current = nextValueStr;
100101
setValue(newValue);
101102
}
102103
});

tests/useWatch.test.tsx

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import { mount } from 'enzyme';
33
import type { FormInstance } from '../src';
44
import { List } from '../src';
55
import Form, { Field } from '../src';
66
import timeout from './common/timeout';
77
import { act } from 'react-dom/test-utils';
88
import { Input } from './common/InfoField';
9+
import { stringify } from '../src/useWatch';
910

1011
describe('useWatch', () => {
1112
let staticForm: FormInstance<any>;
@@ -350,4 +351,45 @@ describe('useWatch', () => {
350351

351352
expect(updateA > updateB).toBeTruthy();
352353
});
354+
355+
it('mount while unmount', () => {
356+
const Demo = () => {
357+
const [form] = Form.useForm();
358+
const [type, setType] = useState(true);
359+
const name = Form.useWatch<string>('name', form);
360+
361+
return (
362+
<Form form={form}>
363+
<button type="button" onClick={() => setType(c => !c)}>
364+
type
365+
</button>
366+
{type && (
367+
<Field name="name" key="a">
368+
<Input />
369+
</Field>
370+
)}
371+
{!type && (
372+
<Field name="name" key="b">
373+
<Input />
374+
</Field>
375+
)}
376+
<div className="value">{name}</div>
377+
</Form>
378+
);
379+
};
380+
381+
const wrapper = mount(<Demo />);
382+
wrapper
383+
.find('input')
384+
.first()
385+
.simulate('change', { target: { value: 'bamboo' } });
386+
wrapper.find('button').at(0).simulate('click');
387+
expect(wrapper.find('.value').text()).toEqual('bamboo');
388+
});
389+
it('stringify error', () => {
390+
const obj: any = {};
391+
obj.name = obj;
392+
const str = stringify(obj);
393+
expect(typeof str === 'number').toBeTruthy();
394+
});
353395
});

0 commit comments

Comments
 (0)