【发布时间】:2020-11-12 20:08:01
【问题描述】:
请有人帮忙回答这个问题:
我有 2 个 NumberInput 控件,一个输入,另一个被禁用。我需要在第一个输入字段中输入数字,禁用字段以显示此数字/100。这两个 NumberInput 将具有源字段,这些字段将保存到 simpleform 中的当前记录。
如何在 react-admin 中执行此操作
谢谢
【问题讨论】:
标签: react-admin
请有人帮忙回答这个问题:
我有 2 个 NumberInput 控件,一个输入,另一个被禁用。我需要在第一个输入字段中输入数字,禁用字段以显示此数字/100。这两个 NumberInput 将具有源字段,这些字段将保存到 simpleform 中的当前记录。
如何在 react-admin 中执行此操作
谢谢
【问题讨论】:
标签: react-admin
最简单的方法是使用Linking two inputs部分下的文档中描述的方法
本质上:您可以创建自己的输入组件,您可以在其中通过钩子useFormState 访问表单值。然后只需按照您想要的方式分配所需的值,例如除以 100。
编辑
找到了一种更简洁的方法 - 使用 final-form-calculate 创建装饰器并将其传递给 <FormWithRedirect /> 组件,如下所示:
import createDecorator from 'final-form-calculate'
const calculator = createDecorator(
// Calculations:
{
field: 'number1', // when the value of foo changes...
updates: {
number2: (fooValue, allValues) => allValues["number1"] * 2
}
})
...
<FormWithRedirect
...
decorators={[calculator]}
/>
看看这个code sandbox
【讨论】:
<FormDataConsumer>
{({ formData }) => (
<NumberInput defaultValue={formData.my_first_input / 100} source="second_input"/>
)}
</FormDataConsumer>
import { useFormState } from 'react-final-form';
...
const { values: { my_first_input }} = useFormState({ subscription: { values: true } });
...
<NumberInput defaultValue={my_first_input / 100} source="second_input"/>
来源:https://marmelab.com/react-admin/Inputs.html#linking-two-inputs
您需要使用 react-final-form 的 useForm 挂钩来使您的输入动态化:
import { useForm, useFormState } from 'react-final-form';
...
const {change} = useForm();
const { values: { my_first_input }} = useFormState({ subscription: { values: true } });
useEffect(() => {
change('my_second_input', my_first_input / 100);
}, [change, my_first_input]);
...
<NumberInput defaultValue={my_first_input / 100} source="second_input"/>
【讨论】:
useForm 钩子。
useForm 需要在inside 表单中调用,因此您需要将组件一分为二,一次使用SimpleForm,另一次使用它的子组件,您可以在其中实际调用useForm,因为它被包裹在SimpleForm中。
NumberInput就像在这里描述marmelab.com/react-admin/…。这也可以让您同时使用 useForm 和 useFormState 钩子。
我对这个问题有一个更简短的解决方案: 我所做的只是在 FormDataConsumer 中进行计算。现在,我可以得到计算值,它会更新数组中的正确记录。
谢谢
<FormDataConsumer>
{({
formData, // The whole form data
scopedFormData, // The data for this item of the ArrayInput
getSource, // A function to get the valid source inside an ArrayInput
...rest
}) => {
if (typeof scopedFormData !== 'undefined') {
scopedFormData.total = scopedFormData.quantity * scopedFormData.unitprice;
return (
<NumberInput disabled defaultValue={scopedFormData.total} label="Total" source={getSource('total')} />
)
} else {
return(
<NumberInput disabled label="Total" source={getSource('total')} />
)
}
}}
【讨论】: