From 2801509bd1c8b68e3d188cd1240e65d1828671fd Mon Sep 17 00:00:00 2001
From: 97vack <1739717921@qq.com>
Date: Tue, 26 Dec 2023 01:38:57 +0000
Subject: [PATCH 1/4] fix: Fixed model type prompt error bug when using
useWatch
---
docs/demos/_watch.tsx | 2 +-
src/use/useForm.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/demos/_watch.tsx b/docs/demos/_watch.tsx
index aee2bed..2dca542 100644
--- a/docs/demos/_watch.tsx
+++ b/docs/demos/_watch.tsx
@@ -8,7 +8,7 @@ export default function App() {
const renderAge = render('age')();
useWatch(
- ({ model }) => [model?.name, model?.age],
+ ({ model }) => [model.name, model.age],
(value, preValue) => {
console.log({ value, preValue });
},
diff --git a/src/use/useForm.ts b/src/use/useForm.ts
index 30d7872..e24e298 100644
--- a/src/use/useForm.ts
+++ b/src/use/useForm.ts
@@ -10,7 +10,7 @@ import { usePrivateSubscribe } from './useSubscribe';
import { usePrivateWatch } from './useWatch';
const useForm = >(
- model?: T,
+ model: T,
config?: UseFormNamespace.ShareConfig,
) => {
const proxyTarget = useRef(model || {});
From 2386dc01ef693b78c3f359836419e1d69a3a1422 Mon Sep 17 00:00:00 2001
From: 97vack <1739717921@qq.com>
Date: Tue, 26 Dec 2023 01:44:02 +0000
Subject: [PATCH 2/4] fix: fix the bug that prompts setState() method type
incompatibility when using type UseFormReturnType
---
src/types/use.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/types/use.ts b/src/types/use.ts
index 8d9f81e..89cc305 100644
--- a/src/types/use.ts
+++ b/src/types/use.ts
@@ -85,7 +85,7 @@ export namespace UseFormNamespace {
* @description Manually re-render the view. If you need to re-render the view externally, you can call setState to re-render the current component tree.
* @resetType Function
*/
- setState: () => React.Dispatch>;
+ setState: () => void;
} & Apis.FormApis &
Pick;
}
From 360f00b6ec1cc13872fab65a9ad3ff7edafcfa3b Mon Sep 17 00:00:00 2001
From: 97vack <1739717921@qq.com>
Date: Tue, 26 Dec 2023 02:55:44 +0000
Subject: [PATCH 3/4] feat: Optimize the release of memory resources after
destruction when using useForm
---
.dumi/metadata/apis/docs_apiDemos_Form.json | 24 +++++++++++++++----
.../metadata/apis/docs_apiDemos_FormItem.json | 21 +++++++++++++---
.../metadata/apis/docs_apiDemos_useForm.json | 21 +++++++++++++---
.../apis/docs_apiDemos_useFormReturnType.json | 2 +-
docs/demos/_controller.tsx | 7 ++++--
docs/demos/_example.tsx | 7 ++++--
src/types/form.ts | 5 +++-
src/use/useController.ts | 15 +++++++++---
src/use/useForm.ts | 7 ++++++
src/utils/controller.ts | 14 +++++++----
10 files changed, 100 insertions(+), 23 deletions(-)
diff --git a/.dumi/metadata/apis/docs_apiDemos_Form.json b/.dumi/metadata/apis/docs_apiDemos_Form.json
index 2394c09..f1d2dac 100644
--- a/.dumi/metadata/apis/docs_apiDemos_Form.json
+++ b/.dumi/metadata/apis/docs_apiDemos_Form.json
@@ -19,7 +19,8 @@
},
"tags": {
"description": "Error prompt class name.",
- "localKey": "API.form.global.props.form.share.errorClass"
+ "localKey": "API.form.global.props.form.share.errorClass",
+ "version": "1.3.4"
}
},
"labelPosition": {
@@ -66,7 +67,8 @@
},
"tags": {
"description": "Label class name",
- "localKey": "API.form.global.props.form.share.labelClass"
+ "localKey": "API.form.global.props.form.share.labelClass",
+ "version": "1.3.4"
}
},
"formItemStyle": {
@@ -88,7 +90,8 @@
},
"tags": {
"description": "Form item class",
- "localKey": "API.form.global.props.form.share.formItemClass"
+ "localKey": "API.form.global.props.form.share.formItemClass",
+ "version": "1.3.4"
}
},
"trigger": {
@@ -115,6 +118,18 @@
"description": "Form item content style, supports object nesting writing method"
}
},
+ "contentClassName": {
+ "defaultValue": null,
+ "name": "contentClassName",
+ "type": {
+ "name": "string"
+ },
+ "tags": {
+ "description": "Content area style class name",
+ "localKey": "API.form.global.props.form.share.contentClass",
+ "version": "1.3.4"
+ }
+ },
"fullWidth": {
"defaultValue": {
"value": "false"
@@ -197,7 +212,8 @@
},
"tags": {
"description": "Form container class name.",
- "localKey": "API.form.global.props.form.formClass"
+ "localKey": "API.form.global.props.form.formClass",
+ "version": "1.3.4"
}
},
"direction": {
diff --git a/.dumi/metadata/apis/docs_apiDemos_FormItem.json b/.dumi/metadata/apis/docs_apiDemos_FormItem.json
index 37cb00a..db829bd 100644
--- a/.dumi/metadata/apis/docs_apiDemos_FormItem.json
+++ b/.dumi/metadata/apis/docs_apiDemos_FormItem.json
@@ -125,7 +125,8 @@
},
"tags": {
"description": "Error prompt class name.",
- "localKey": "API.form.global.props.form.share.errorClass"
+ "localKey": "API.form.global.props.form.share.errorClass",
+ "version": "1.3.4"
}
},
"labelPosition": {
@@ -172,7 +173,8 @@
},
"tags": {
"description": "Label class name",
- "localKey": "API.form.global.props.form.share.labelClass"
+ "localKey": "API.form.global.props.form.share.labelClass",
+ "version": "1.3.4"
}
},
"formItemStyle": {
@@ -194,7 +196,8 @@
},
"tags": {
"description": "Form item class",
- "localKey": "API.form.global.props.form.share.formItemClass"
+ "localKey": "API.form.global.props.form.share.formItemClass",
+ "version": "1.3.4"
}
},
"trigger": {
@@ -221,6 +224,18 @@
"description": "Form item content style, supports object nesting writing method"
}
},
+ "contentClassName": {
+ "defaultValue": null,
+ "name": "contentClassName",
+ "type": {
+ "name": "string"
+ },
+ "tags": {
+ "description": "Content area style class name",
+ "localKey": "API.form.global.props.form.share.contentClass",
+ "version": "1.3.4"
+ }
+ },
"fullWidth": {
"defaultValue": {
"value": "false"
diff --git a/.dumi/metadata/apis/docs_apiDemos_useForm.json b/.dumi/metadata/apis/docs_apiDemos_useForm.json
index 55a9318..ac3b0a4 100644
--- a/.dumi/metadata/apis/docs_apiDemos_useForm.json
+++ b/.dumi/metadata/apis/docs_apiDemos_useForm.json
@@ -43,7 +43,8 @@
},
"tags": {
"description": "Error prompt class name.",
- "localKey": "API.form.global.props.form.share.errorClass"
+ "localKey": "API.form.global.props.form.share.errorClass",
+ "version": "1.3.4"
}
},
"labelPosition": {
@@ -90,7 +91,8 @@
},
"tags": {
"description": "Label class name",
- "localKey": "API.form.global.props.form.share.labelClass"
+ "localKey": "API.form.global.props.form.share.labelClass",
+ "version": "1.3.4"
}
},
"formItemStyle": {
@@ -112,7 +114,8 @@
},
"tags": {
"description": "Form item class",
- "localKey": "API.form.global.props.form.share.formItemClass"
+ "localKey": "API.form.global.props.form.share.formItemClass",
+ "version": "1.3.4"
}
},
"trigger": {
@@ -139,6 +142,18 @@
"description": "Form item content style, supports object nesting writing method"
}
},
+ "contentClassName": {
+ "defaultValue": null,
+ "name": "contentClassName",
+ "type": {
+ "name": "string"
+ },
+ "tags": {
+ "description": "Content area style class name",
+ "localKey": "API.form.global.props.form.share.contentClass",
+ "version": "1.3.4"
+ }
+ },
"fullWidth": {
"defaultValue": {
"value": "false"
diff --git a/.dumi/metadata/apis/docs_apiDemos_useFormReturnType.json b/.dumi/metadata/apis/docs_apiDemos_useFormReturnType.json
index 6b204dd..9846173 100644
--- a/.dumi/metadata/apis/docs_apiDemos_useFormReturnType.json
+++ b/.dumi/metadata/apis/docs_apiDemos_useFormReturnType.json
@@ -51,7 +51,7 @@
"defaultValue": null,
"name": "setState",
"type": {
- "name": "() => Dispatch"
+ "name": "() => void"
},
"tags": {
"localKey": "API.useForm.setState.desc",
diff --git a/docs/demos/_controller.tsx b/docs/demos/_controller.tsx
index a5784b0..762e871 100644
--- a/docs/demos/_controller.tsx
+++ b/docs/demos/_controller.tsx
@@ -1,10 +1,12 @@
import Button from '@components/Button';
-import React, { useEffect } from 'react';
+import React, { useEffect, useState } from 'react';
import { useForm } from 'react-form-simple';
export default function App() {
const { render, model } = useForm({ name: 'name' });
+ const [modelState, setModelState] = useState('');
+
const renderName = render('name')();
useEffect(() => {
@@ -13,11 +15,12 @@ export default function App() {
}, 2000);
}, []);
- const onSubmit = () => void console.log(model);
+ const onSubmit = () => setModelState(JSON.stringify(model));
return (
<>
{renderName}
+ {modelState}
>
);
diff --git a/docs/demos/_example.tsx b/docs/demos/_example.tsx
index 9f56ae2..ee2e8a5 100644
--- a/docs/demos/_example.tsx
+++ b/docs/demos/_example.tsx
@@ -1,5 +1,5 @@
import Button from '@components/Button';
-import React from 'react';
+import React, { useState } from 'react';
import { useForm } from 'react-form-simple';
export default function App() {
@@ -7,17 +7,20 @@ export default function App() {
name: '',
age: '',
});
+ const [modelState, setModelState] = useState('');
+
const renderName = render('name')();
const renderAge = render('age')();
const renderSubmit = (
-
+
);
return (
<>
{renderName}
{renderAge}
+ {modelState}
{renderSubmit}
>
);
diff --git a/src/types/form.ts b/src/types/form.ts
index 89d3484..3dc0aa8 100644
--- a/src/types/form.ts
+++ b/src/types/form.ts
@@ -327,8 +327,10 @@ export namespace GlobalProps {
contentStyle?: CSSInterpolation;
/**
* @description Content area style class name
+ * @localKey API.form.global.props.form.share.contentClass
+ * @version 1.3.4
*/
- contentClassName?: string
+ contentClassName?: string;
/**
* @localKey API.form.global.props.form.share.fullWidth
* @description Whether the width of the form item fills the entire row
@@ -374,6 +376,7 @@ export namespace GlobalProps {
/**
* @description Form container class name.
* @localKey API.form.global.props.form.formClass
+ * @version 1.3.4
*/
formClassName?: string;
/**
diff --git a/src/use/useController.ts b/src/use/useController.ts
index 995384e..584750a 100644
--- a/src/use/useController.ts
+++ b/src/use/useController.ts
@@ -5,9 +5,18 @@ export function useController>(obj: T): T {
const [, setState] = useState({});
const proxyStateRef = useRef(obj);
- return observer(proxyStateRef.current, () => {
- setState({});
- });
+ const { proxyMap, rawMap } = useRef({
+ proxyMap: new WeakMap(),
+ rawMap: new WeakMap(),
+ }).current;
+
+ return observer(
+ proxyStateRef.current,
+ () => {
+ setState({});
+ },
+ { proxyMap, rawMap },
+ );
}
export default useController;
diff --git a/src/use/useForm.ts b/src/use/useForm.ts
index e24e298..623ba64 100644
--- a/src/use/useForm.ts
+++ b/src/use/useForm.ts
@@ -27,6 +27,11 @@ const useForm = >(
[],
);
+ const createObserverMap = useRef({
+ proxyMap: new WeakMap(),
+ rawMap: new WeakMap(),
+ }).current;
+
const proxymodel = createObserverForm(
proxyTarget.current as T,
({ path, value }) => {
@@ -36,6 +41,7 @@ const useForm = >(
},
{
path: [],
+ ...createObserverMap,
},
);
@@ -68,6 +74,7 @@ const useForm = >(
useWatch,
setState: useFormExtraApis.setState,
...overlayApis,
+ ...createObserverMap,
};
};
diff --git a/src/utils/controller.ts b/src/utils/controller.ts
index f9b6198..f88b400 100644
--- a/src/utils/controller.ts
+++ b/src/utils/controller.ts
@@ -6,14 +6,21 @@ import { isObject, isObjectOrArray } from './util';
export const proxyMap = new WeakMap();
export const rawMap = new WeakMap();
+const _proxyMap = proxyMap;
+const _rawMap = rawMap;
+
const proxyPolyfill = ProxyPolyfillBuilder();
const Proxys = window.Proxy || proxyPolyfill;
-export type ObserverOptions = { path?: string[] };
+export type ObserverOptions = {
+ path?: string[];
+ proxyMap?: WeakMap