如何在 React 中使用带有 Formik 的自定义输入?
How to use custom Input with Formik in React?
我正在尝试使用 DatePicker within Formik。但是当我点击 DatePicker 的日期时,它的表单值没有改变。相反,我得到了这个错误:
Uncaught TypeError: e.persist is not a function
at Formik._this.handleChange (formik.es6.js:5960)
我把代码简写一下,代码如下
const SomeComponent = () => (
<Formik
render={({
values,
handleSubmit,
handleChange,
setFieldValue
}) => {
return (
<div>
<form onSubmit={handleSubmit}>
<DatePicker
name={'joinedAt'}
value={values['joinedAt']}
onChange={handleChange}
/>
</form>
</div>
)
}}
/>
)
我用谷歌搜索了一些文件,https://github.com/jaredpalmer/formik/issues/187 and https://github.com/jaredpalmer/formik/issues/86
所以我尝试了下面的方法,但它不起作用。
...setFieldValue
<DatePicker
name={'joinedAt'}
value={values['joinedAt']}
onChange={setFieldValue}
/>
https://github.com/jaredpalmer/formik/issues/692
如果您使用 setFieldValue 方法,则需要手动设置值
我这样解决这个问题
<DatePicker
name={'joinedAt'}
value={values['joinedAt']}
onChange={e => setFieldValue('joinedAt', e)}
/>
2020-03-08更新:
您可以在 setFieldValue 的第二个道具上使用 e.target.value
,具体取决于您的自定义输入设计。感谢布兰登。
对于 html 原始输入字段 handleChange 就像一个魅力,但对于自定义组件,您必须使用 setFieldValue
强制更改值。
onChange={e => setFieldValue('joinedAt', e)}
已接受的答案对我无效,并且未显示所选日期。已经快一年了,所以实施可能会有一些变化。虽然这可以通过使用 toDateString()
这样
来解决
<DatePicker
name={'joinedAt'}
value={values['joinedAt']}
onChange={e => setFieldValue('joinedAt', e.toDateString())}
/>
如果你有更深的嵌套,你应该使用 Formik Field。
示例:
<Formik
validationSchema={schema}
initialValues={initialValues}
onSubmit={(values, actions) => {}}
>
<Field name="colors" component={ColorsEditor} colors={colorArray}/>
</Formik>
const ColorsEditor = ({ field, colors, form, ...props }) => {
return (
<div>
<Button onClick={() => form.setFieldValue('colors', "myValue")}>
</Button>
</div>
)
}
所以 Field 组件已经包含表单,其中包含您可以在需要的地方使用的 setFieldValue。它还包括用于其他自定义的错误和所需字段。
Formik 的解决方案是 useField()
方法。您可能需要为您可能没有源代码访问权限的 DatePicker 等组件创建一个包装器。
documentation提供了一个例子:
const MyTextField = ({ label, ...props }) => {
const [field, meta, helpers] = useField(props);
return (
<>
<label>
{label}
<input {...field} {...props} />
</label>
{meta.touched && meta.error ? (
<div className="error">{meta.error}</div>
) : null}
</>
);
};
简而言之,该方法采用描述字段的自定义道具。然后你可以在自定义字段中扩展分配的字段值和道具。
我正在尝试使用 DatePicker within Formik。但是当我点击 DatePicker 的日期时,它的表单值没有改变。相反,我得到了这个错误:
Uncaught TypeError: e.persist is not a function at Formik._this.handleChange (formik.es6.js:5960)
我把代码简写一下,代码如下
const SomeComponent = () => (
<Formik
render={({
values,
handleSubmit,
handleChange,
setFieldValue
}) => {
return (
<div>
<form onSubmit={handleSubmit}>
<DatePicker
name={'joinedAt'}
value={values['joinedAt']}
onChange={handleChange}
/>
</form>
</div>
)
}}
/>
)
我用谷歌搜索了一些文件,https://github.com/jaredpalmer/formik/issues/187 and https://github.com/jaredpalmer/formik/issues/86
所以我尝试了下面的方法,但它不起作用。
...setFieldValue
<DatePicker
name={'joinedAt'}
value={values['joinedAt']}
onChange={setFieldValue}
/>
https://github.com/jaredpalmer/formik/issues/692
如果您使用 setFieldValue 方法,则需要手动设置值
我这样解决这个问题
<DatePicker
name={'joinedAt'}
value={values['joinedAt']}
onChange={e => setFieldValue('joinedAt', e)}
/>
2020-03-08更新:
您可以在 setFieldValue 的第二个道具上使用 e.target.value
,具体取决于您的自定义输入设计。感谢布兰登。
对于 html 原始输入字段 handleChange 就像一个魅力,但对于自定义组件,您必须使用 setFieldValue
强制更改值。
onChange={e => setFieldValue('joinedAt', e)}
已接受的答案对我无效,并且未显示所选日期。已经快一年了,所以实施可能会有一些变化。虽然这可以通过使用 toDateString()
这样
<DatePicker
name={'joinedAt'}
value={values['joinedAt']}
onChange={e => setFieldValue('joinedAt', e.toDateString())}
/>
如果你有更深的嵌套,你应该使用 Formik Field。 示例:
<Formik
validationSchema={schema}
initialValues={initialValues}
onSubmit={(values, actions) => {}}
>
<Field name="colors" component={ColorsEditor} colors={colorArray}/>
</Formik>
const ColorsEditor = ({ field, colors, form, ...props }) => {
return (
<div>
<Button onClick={() => form.setFieldValue('colors', "myValue")}>
</Button>
</div>
)
}
所以 Field 组件已经包含表单,其中包含您可以在需要的地方使用的 setFieldValue。它还包括用于其他自定义的错误和所需字段。
Formik 的解决方案是 useField()
方法。您可能需要为您可能没有源代码访问权限的 DatePicker 等组件创建一个包装器。
documentation提供了一个例子:
const MyTextField = ({ label, ...props }) => {
const [field, meta, helpers] = useField(props);
return (
<>
<label>
{label}
<input {...field} {...props} />
</label>
{meta.touched && meta.error ? (
<div className="error">{meta.error}</div>
) : null}
</>
);
};
简而言之,该方法采用描述字段的自定义道具。然后你可以在自定义字段中扩展分配的字段值和道具。