【问题标题】:Formik Form not updating with onclickFormik 表单未通过 onclick 更新
【发布时间】:2021-01-25 18:54:12
【问题描述】:

我有一个自定义事件处理程序(单击按钮时),它根据下拉选择在嵌套数组中注入数据。事件处理程序添加数据后,表单无法正确更新。在表单的任何其他输入上调用任何其他事件处理程序将触发表单更新。数据设置正确,但在初始 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>

【问题讨论】:

  • 有趣的是,我在尝试使用 Formik 时遇到了许多错误。如果您不能以合理的速度通过这一点,那么明智的做法可能是另辟蹊径。

标签: reactjs formik


【解决方案1】:

您正在改变导致问题的状态对象。如果您在addLanguageValue 中创建一个新对象,它会按预期工作:

  function addLanguageValue() {
    setQuestionnaire({
      ...questionnaire,
      questions: [...questionnaire.questions, questionnaire.selectedLanguage]
    });
  }

Sandbox example

【讨论】:

    【解决方案2】:

    由于 onClick 函数不会导致重新渲染状态,因此您可以使用以下解决方法/技巧,将无害的函数用作 setStatus 来触发重新渲染:

    <button
      type='button'
      className='bg-gradient-to-b'
      onClick={e => {
        addLanguageValue(values);
        //Used for rerendering.
        props.setStatus('Adding language!');
      }}
    >
      Add language
    </button>;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多