如何在 React-Final-Form 中收听 onChange 的字段组件?



Redux-form "Field" 组件提供 onChange 属性。每当从基础输入触发 onChange 事件时将调用的回调。此回调允许获取字段的"newValue"和"previousValue"。

反应最终形式的"字段"组件没有此属性。

那么,我怎样才能获得相同的功能呢?

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

更改检测下的想法是订阅Field的值更改,并在值实际更改时调用自定义onChange处理程序。我准备了简化的示例,您可以在其中看到它的实际效果。详细信息MyField.js文件中。

因此,您可以像使用它一样使用它redux-form

<MyField 
component="input"
name="firstName"
onChange={(val, prevVal) => console.log(val, prevVal)}
/>

2022 年 1 月更新

虽然上面的代码仍然有效(检查沙盒版本(,但在某些情况下,解决方案需要更多周。

这是一个更新的沙盒,其中包含通过钩子实现的沙箱。它基于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

我没有使用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 的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组件中,我们可以侦听字段值的更改,并且 知道字段是否处于活动状态,推断字段何时处于活动状态 由于外部影响,价值会发生变化。

通过 -反应最终形式的Github 文档


以下是React-Final-Form文档中提供的沙盒示例: https://codesandbox.io/s/3x989zl866

相关内容

  • 没有找到相关文章