React-Final-Form中如何监听Field组件的onChange?
How to listen to onChange of the Field component in React-Final-Form?
Redux-form "Field" component provides onChange property。每当从基础输入触发 onChange 事件时将调用的回调。此回调允许为字段获取 "newValue" 和 "previousValue"。
React-final-form "Field" 组件没有这个 属性.
那么,我怎样才能获得相同的功能?
您需要使用 ExternalModificationDetector
组件来监听字段组件的变化,如下所示:
<ExternalModificationDetector name="abc">
{externallyModified => (
<BooleanDecay value={externallyModified} delay={1000}>
{highlight => (
<Field
//field properties here
/>
)}
</BooleanDecay>
)}
</ExternalModificationDetector>
By wrapping a stateful ExternalModificationDetector
component in a
Field
component, we can listen for changes to a field's value, and by
knowing whether or not the field is active, deduce when a field's
value changes due to external influences.
Via - React-Final-Form Github Docs
这是 沙盒示例,在 React-Final-Form 文档中提供:https://codesandbox.io/s/3x989zl866
更改检测的想法是订阅 Field
的值更改,并在值实际更改时调用您的自定义 onChange
处理程序。我准备了 simplified example,您可以在其中看到它的实际效果。详细信息在 MyField.js
文件中。
因此您可以像 redux-form
:
一样使用它
<MyField
component="input"
name="firstName"
onChange={(val, prevVal) => console.log(val, prevVal)}
/>
2022 年 1 月更新
虽然上面的代码仍然有效(检查沙盒版本),但有时解决方案需要 。
Here is 一个更新的沙箱,通过挂钩实现。它基于 useFieldValue
挂钩和 OnChange
组件作为此挂钩的使用者。但是当您需要重新渲染之间的先前值时,可以单独使用挂钩本身。此解决方案不依赖于字段的 meta.active
。
// useFieldValue.js
import { useEffect, useRef } from "react";
import { useField } from "react-final-form";
const usePrevious = (val) => {
const ref = useRef(val);
useEffect(() => {
ref.current = val;
}, [val]);
return ref.current;
};
const useFieldValue = (name) => {
const {
input: { value }
} = useField(name, { subscription: { value: true } });
const prevValue = usePrevious(value);
return [value, prevValue];
};
export default useFieldValue;
// OnChange.js
import { useEffect } from "react";
import useFieldValue from "./useFieldValue";
export default ({ name, onChange }) => {
const [value, prevValue] = useFieldValue(name);
useEffect(() => {
if (value !== prevValue) {
onChange(value, prevValue);
}
}, [onChange, value, prevValue]);
return null;
};
另一个不错的选择是这个答案:
我没有使用过 redux-form,但是我在 Field 组件周围添加了一个超级简单的包装器来像这样监听 onChange:
const Input = props => {
const {
name,
validate,
onChange,
...rest
} = props;
return (
<Field name={name} validate={validate}>
{({input, meta}) => {
return (
<input
{...input}
{...rest}
onChange={(e) => {
input.onChange(e); //final-form's onChange
if (onChange) { //props.onChange
onChange(e);
}
}}
/>
)}}
</Field>
);
};
React-final-form 使用微型外部包处理此功能。
基本上,它是一个附加组件,可以添加到使用其名称绑定到元素的表单中:
<Field name="foo" component="input" type="checkbox" />
<OnChange name="foo">
{(value, previous) => {
// do something
}}
</OnChange>
可在此处找到当前文档:
https://github.com/final-form/react-final-form-listeners#onchange
可以使用字段的 parse
属性并提供一个函数来执行您需要的值:
<Field
parse={value => {
// Do what you want with `value`
return value;
}}
// ...
/>
Redux-form "Field" component provides onChange property。每当从基础输入触发 onChange 事件时将调用的回调。此回调允许为字段获取 "newValue" 和 "previousValue"。
React-final-form "Field" 组件没有这个 属性.
那么,我怎样才能获得相同的功能?
您需要使用 ExternalModificationDetector
组件来监听字段组件的变化,如下所示:
<ExternalModificationDetector name="abc">
{externallyModified => (
<BooleanDecay value={externallyModified} delay={1000}>
{highlight => (
<Field
//field properties here
/>
)}
</BooleanDecay>
)}
</ExternalModificationDetector>
By wrapping a stateful
ExternalModificationDetector
component in aField
component, we can listen for changes to a field's value, and by knowing whether or not the field is active, deduce when a field's value changes due to external influences.Via - React-Final-Form Github Docs
这是 沙盒示例,在 React-Final-Form 文档中提供:https://codesandbox.io/s/3x989zl866
更改检测的想法是订阅 Field
的值更改,并在值实际更改时调用您的自定义 onChange
处理程序。我准备了 simplified example,您可以在其中看到它的实际效果。详细信息在 MyField.js
文件中。
因此您可以像 redux-form
:
<MyField
component="input"
name="firstName"
onChange={(val, prevVal) => console.log(val, prevVal)}
/>
2022 年 1 月更新
虽然上面的代码仍然有效(检查沙盒版本),但有时解决方案需要
Here is 一个更新的沙箱,通过挂钩实现。它基于 useFieldValue
挂钩和 OnChange
组件作为此挂钩的使用者。但是当您需要重新渲染之间的先前值时,可以单独使用挂钩本身。此解决方案不依赖于字段的 meta.active
。
// useFieldValue.js
import { useEffect, useRef } from "react";
import { useField } from "react-final-form";
const usePrevious = (val) => {
const ref = useRef(val);
useEffect(() => {
ref.current = val;
}, [val]);
return ref.current;
};
const useFieldValue = (name) => {
const {
input: { value }
} = useField(name, { subscription: { value: true } });
const prevValue = usePrevious(value);
return [value, prevValue];
};
export default useFieldValue;
// OnChange.js
import { useEffect } from "react";
import useFieldValue from "./useFieldValue";
export default ({ name, onChange }) => {
const [value, prevValue] = useFieldValue(name);
useEffect(() => {
if (value !== prevValue) {
onChange(value, prevValue);
}
}, [onChange, value, prevValue]);
return null;
};
另一个不错的选择是这个答案:
我没有使用过 redux-form,但是我在 Field 组件周围添加了一个超级简单的包装器来像这样监听 onChange:
const Input = props => {
const {
name,
validate,
onChange,
...rest
} = props;
return (
<Field name={name} validate={validate}>
{({input, meta}) => {
return (
<input
{...input}
{...rest}
onChange={(e) => {
input.onChange(e); //final-form's onChange
if (onChange) { //props.onChange
onChange(e);
}
}}
/>
)}}
</Field>
);
};
React-final-form 使用微型外部包处理此功能。
基本上,它是一个附加组件,可以添加到使用其名称绑定到元素的表单中:
<Field name="foo" component="input" type="checkbox" />
<OnChange name="foo">
{(value, previous) => {
// do something
}}
</OnChange>
可在此处找到当前文档:
https://github.com/final-form/react-final-form-listeners#onchange
可以使用字段的 parse
属性并提供一个函数来执行您需要的值:
<Field
parse={value => {
// Do what you want with `value`
return value;
}}
// ...
/>