Redux-form "Field" 组件提供onChange 属性。每当从底层输入触发 onChange 事件时将调用的回调。此回调允许获取字段的“newValue”和“previousValue”。
React-final-form "Field" 组件没有这个属性。
那么,我怎样才能获得相同的功能呢?
Redux-form "Field" 组件提供onChange 属性。每当从底层输入触发 onChange 事件时将调用的回调。此回调允许获取字段的“newValue”和“previousValue”。
React-final-form "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
我没有使用 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>
);
};
更改检测下的想法是订阅值更改并在值实际更改时Field
调用您的自定义处理程序。onChange
我准备了简化的示例,您可以在其中看到它的实际效果。详细信息在MyField.js
文件中。
结果,您可以像使用它一样使用它redux-form
:
<MyField
component="input"
name="firstName"
onChange={(val, prevVal) => console.log(val, prevVal)}
/>
虽然上面的代码仍然有效(检查沙盒版本),但有时解决方案需要更多的时间。
这是一个更新的沙箱,通过钩子实现。它基于一个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;
};
另一个不错的选择是这个答案:https ://stackoverflow.com/a/56495998/3647991
可以使用字段的parse
属性并提供一个函数来满足您对值的需求:
<Field
parse={value => {
// Do what you want with `value`
return value;
}}
// ...
/>
您需要使用该ExternalModificationDetector
组件来监听字段组件上的更改,如下所示:
<ExternalModificationDetector name="abc">
{externallyModified => (
<BooleanDecay value={externallyModified} delay={1000}>
{highlight => (
<Field
//field properties here
/>
)}
</BooleanDecay>
)}
</ExternalModificationDetector>
ExternalModificationDetector
通过在组件中 封装一个有状态的Field
组件,我们可以监听字段值的变化,并通过知道字段是否处于活动状态,推断出字段值何时因外部影响而发生变化。Via - React-Final-Form Github Docs
这是React-Final-Form文档中提供的沙盒示例: https ://codesandbox.io/s/3x989zl866