【问题标题】:Resetting a formik form in react-native on navigation在导航上的 react-native 中重置 formik 表单
【发布时间】:2021-09-15 10:41:19
【问题描述】:

我正在尝试创建一个可以创建和编辑实体的 React Native 应用程序。

例如,用户。

我有一个包含名字和姓氏的 formik 表格,以及一个电子邮件地址。 如果传递了用户参数,则表单应采用这些值。

但是,它只能在第一次工作。之后,表单将保留第一个值。

如何强制重新评估表单?

function FormScreen({ navigation, route }) {
  const formikRef = React.createRef();
  const initialValues = { firstName: "", lastName: "", email: "" };

  if (route.params && route.params.user) {
    if (route.params.user.firstName) {
      initialValues.firstName = route.params.user.firstName;
    }
    if (route.params.user.lastName) {
      initialValues.lastName = route.params.user.lastName;
    }
    if (route.params.user.email) {
      initialValues.email = route.params.user.email;
    }
  }

  const unsubscribeBlur = navigation.addListener("blur", (e) => {
    console.log("form blur");
    if (formikRef.current) {
      console.log("form reset");
      formikRef.current?.resetForm();
    }
  });

  return (
    <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
      <Formik
        innerRef={formikRef}
        initialValues={initialValues}
        validationSchema={Yup.object({
          firstName: Yup.string()
            .max(15, "Must be 15 characters or less")
            .required("Required"),
          lastName: Yup.string()
            .max(20, "Must be 20 characters or less")
            .required("Required"),
          email: Yup.string()
            .email("Invalid email address")
            .required("Required"),
        })}
        onSubmit={(values, { setSubmitting }) => {
          setTimeout(() => {
            alert(JSON.stringify(values, null, 2));
            setSubmitting(false);
          }, 400);
        }}
      >
        <Form>
          <label htmlFor="firstName">First Name</label>
          <Field name="firstName" type="text" />
          <ErrorMessage name="firstName" />

          <label htmlFor="lastName">Last Name</label>
          <Field name="lastName" type="text" />
          <ErrorMessage name="lastName" />

          <label htmlFor="email">Email Address</label>
          <Field name="email" type="email" />
          <ErrorMessage name="email" />

          <button type="submit">Submit</button>
        </Form>
      </Formik>
    </View>
  );
}

export default FormScreen;

我有代码可以在模糊时重置表单,但重置似乎没有任何作用。

您可以在小吃中找到完整的代码。 https://snack.expo.io/@hackzilla/create-and-edit-with-formik

【问题讨论】:

    标签: react-native expo formik react-navigation-v5


    【解决方案1】:

    我们可以在提交后重置表单,这样它就会清除所有字段。请尝试用下面提到的代码替换您的提交方法。

     onSubmit={(values, { setSubmitting, resetForm }) => {
              setTimeout(() => {
                alert(JSON.stringify(values, null, 2));
                setSubmitting(false);
                // reset the fields after submit
                resetForm();
              }, 400);
            }}
    

    【讨论】:

    • 这没关系,但我的问题主要是表格在所有情况下都没有被清除。例如,如果有人开始填写表格,然后决定编辑另一张表格,这将不起作用。
    【解决方案2】:

    因为您使用的是选项卡导航器。当您在它们之间切换时,主屏幕和表单屏幕不会重新安装。因此 formik 不会加载新的 initialValues。以您的方式,您可以在每次聚焦表单屏幕时使用路由参数重置表单。但更好的方法是使用堆栈导航器,每次使用新实例创建表单。

       useFocusEffect(
        React.useCallback(() => {
          if (formikRef.current) {
            console.log("form reset");
            formikRef.current?.setValues(initialValues);
          }
        })
      );
    

    【讨论】:

    • 值得注意的是,我需要第二个参数来使用FocusEffect,并且我还需要调用resetForm 来重置错误消息。 useFocusEffect( React.useCallback(() => { if (formikRef.current) { console.log("form reset"); formikRef.current?.resetForm(); formikRef.current?.setValues(initialValues); } }, [route.params]) );还需要导入: import { useFocusEffect } from "@react-navigation/native";
    • 关键问题是Formik在第一次加载后不会重新加载initialValues。如果你知道这一点,有很多方法可以解决它。
    • 我最终明白了这一点。但缺乏文档令人沮丧。感觉就像我是唯一一个将 formik 放入导航的人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多