Formik 表单未随 onclick 更新
Formik Form not updating with onclick
我有一个自定义事件处理程序(当单击按钮时),它根据下拉选择在嵌套数组中注入数据。事件处理程序添加数据后,表单未正确更新。在表单的任何其他输入上调用任何其他事件处理程序将触发表单更新。数据设置正确但表单在初始 onClick 事件后未正确更新(参见代码)
我设置了 enableReinitialize
https://codesandbox.io/s/updateissue-fy72h
import { useEffect, useState } from "react";
import { Formik, Form, Field, FieldArray, TextField } from "formik";
export default function Design() {
const q = {
questions: ["a", "b", "c", "d"],
selectedLanguage: "nl",
};
const [questionnaire, setQuestionnaire] = useState(q);
function addLanguageValue() {
questionnaire.questions.push(questionnaire.selectedLanguage);
setQuestionnaire(questionnaire);
}
return (
<div>
<Formik
initialValues={questionnaire}
enableReinitialize
onSubmit={() => {}}
>
{({ values, handleChange }) => (
<Form>
<div>
<Field as="select" name="selectedLanguage">
<option value="fr">French</option>
<option value="nl">Dutch</option>
<option value="en">English</option>
</Field>
<button
type="button"
className="bg-gradient-to-b"
onClick={(e) => {
addLanguageValue(values);
}}
>
Add language
</button>
</div>
<div>
<FieldArray
name="questions"
render={(rootHelper) => (
<div>
{values.questions.map((value, j) => {
return <div>{value}</div>;
})}
</div>
)}
/>
</div>
</Form>
)}
</Formik>
您正在改变状态对象,这导致了问题。如果您在 addLanguageValue
中创建一个新对象,它会按预期工作:
function addLanguageValue() {
setQuestionnaire({
...questionnaire,
questions: [...questionnaire.questions, questionnaire.selectedLanguage]
});
}
因为 onClick 函数不会导致状态的重新呈现,您可以使用以下解决方法/技巧,使用无害的函数作为 setStatus 来触发重新呈现:
<button
type='button'
className='bg-gradient-to-b'
onClick={e => {
addLanguageValue(values);
//Used for rerendering.
props.setStatus('Adding language!');
}}
>
Add language
</button>;
我有一个自定义事件处理程序(当单击按钮时),它根据下拉选择在嵌套数组中注入数据。事件处理程序添加数据后,表单未正确更新。在表单的任何其他输入上调用任何其他事件处理程序将触发表单更新。数据设置正确但表单在初始 onClick 事件后未正确更新(参见代码)
我设置了 enableReinitialize
https://codesandbox.io/s/updateissue-fy72h
import { useEffect, useState } from "react";
import { Formik, Form, Field, FieldArray, TextField } from "formik";
export default function Design() {
const q = {
questions: ["a", "b", "c", "d"],
selectedLanguage: "nl",
};
const [questionnaire, setQuestionnaire] = useState(q);
function addLanguageValue() {
questionnaire.questions.push(questionnaire.selectedLanguage);
setQuestionnaire(questionnaire);
}
return (
<div>
<Formik
initialValues={questionnaire}
enableReinitialize
onSubmit={() => {}}
>
{({ values, handleChange }) => (
<Form>
<div>
<Field as="select" name="selectedLanguage">
<option value="fr">French</option>
<option value="nl">Dutch</option>
<option value="en">English</option>
</Field>
<button
type="button"
className="bg-gradient-to-b"
onClick={(e) => {
addLanguageValue(values);
}}
>
Add language
</button>
</div>
<div>
<FieldArray
name="questions"
render={(rootHelper) => (
<div>
{values.questions.map((value, j) => {
return <div>{value}</div>;
})}
</div>
)}
/>
</div>
</Form>
)}
</Formik>
您正在改变状态对象,这导致了问题。如果您在 addLanguageValue
中创建一个新对象,它会按预期工作:
function addLanguageValue() {
setQuestionnaire({
...questionnaire,
questions: [...questionnaire.questions, questionnaire.selectedLanguage]
});
}
因为 onClick 函数不会导致状态的重新呈现,您可以使用以下解决方法/技巧,使用无害的函数作为 setStatus 来触发重新呈现:
<button
type='button'
className='bg-gradient-to-b'
onClick={e => {
addLanguageValue(values);
//Used for rerendering.
props.setStatus('Adding language!');
}}
>
Add language
</button>;