Formik 在渲染新闻之前保留 ols 值

问题描述 投票:0回答:1

我正在使用 React Native,有两个文件:EditGiftScreen.js,它呈现页面以编辑礼物;GiftForm.js,它呈现表单。我还将它用于具有不同道具的 AddGiftScreen.js。

编辑另一个项目后访问编辑功能时出现问题。我第一次访问它时,字段会填充旧礼物的值,然后应用更新。但是,我想直接显示新值。我尝试在表单上使用键,在 GiftForm 上使用另一种状态,并在卸载组件时重置表单,但似乎没有任何效果。

有人有想法吗?

EditGiftScreen.js

import React, { useState, useEffect } from "react";
import { View, Text, StyleSheet } from "react-native";
import api from "../../interceptors/api.js";
import GiftForm from "./GiftForm.js";
import Title from "../Title/Title.js";

function EditGiftScreen({ route, navigation }) {
  const { giftId, selectedChild } = route.params;
  const [apiError, setApiError] = useState(null);
  const [gift, setGift] = useState(null);

  useEffect(() => {
    // Faites une requête à votre API pour récupérer les détails du cadeau
    api
      .get(`/gifts/${giftId}`) // Assurez-vous que l'URL est correcte
      .then((response) => {
        setGift(response.data);
        setApiError(null);
      })
      .catch((error) => {
        console.error(error);
        setApiError(
          `Une erreur est survenue lors de la récupération du cadeau du cadeau, veuillez écrire à ${process.env.CONTACT_EMAIL}.`
        );
      });
  }, [giftId]);

  const handleEditGift = async (values) => {
    try {
      await api.patch(`/gifts/${giftId}`, {
        name: values.giftName,
        url: values.giftUrl,
        details: values.giftDetails,
        price: parseFloat(values.giftPrice),
      });
      setApiError(null);
      if (selectedChild) {
        navigation.navigate("ChildrenList", { currentChild: selectedChild });
      } else {
        navigation.navigate("MyList");
      }
    } catch (error) {
      if (error.response) {
        console.log(error.response.data);
      }
      console.error(error);
      setApiError(
        `Une erreur est survenue lors de la mise à jour du cadeau, veuillez écrire à ${process.env.CONTACT_EMAIL}.`
      );
    }
  };

  return (
    <View style={styles.container}>
      <Title title="Editer une envie" />
      {gift && (
        <GiftForm
          initialValues={{
            giftName: gift.name,
            giftUrl: gift.url,
            giftDetails: gift.details,
            giftPrice: gift.price.toString(),
          }}
          onSubmit={handleEditGift}
          btnTxt={"Mettre à jour"}
          key={gift.id}
        />
      )}
      {apiError && <Text style={styles.apiError}>{apiError}</Text>}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    marginVertical: 20,
    alignItems: "center",
  },
  apiError: {
    color: "red",
    marginTop: 10,
  },
});

export default EditGiftScreen;

GiftForm.js

import React, { useState, useEffect } from "react";
import { View, StyleSheet } from "react-native";
import { Formik } from "formik";
import { giftValidationSchema } from "../../utils/validationSchemas.js";
import FormInput from "../Form/FormInput.js";
import FormButton from "../Form/FormButton.js";

function GiftForm({ initialValues, onSubmit, btnTxt, key }) {
  const [formValues, setFormValues] = useState(initialValues);
  const [isReady, setIsReady] = useState(false);

  useEffect(() => {
    // Mettre à jour les valeurs du formulaire
    setFormValues(initialValues);
    setIsReady(true);
  }, [initialValues]);

  return (
    <>
      {isReady && (
        <Formik
          initialValues={formValues}
          validationSchema={giftValidationSchema}
          onSubmit={onSubmit}
          enableReinitialize={true}
          key={key}
        >
          {({ handleChange, handleSubmit, values, errors, touched }) => (
            <View style={styles.form}>
              <FormInput
                label="Nom du cadeau"
                placeholder={"Entrez le nom du cadeau"}
                value={values.giftName}
                onChangeText={handleChange("giftName")}
                error={touched.giftName && errors.giftName}
              />
              <FormInput
                label="URL du cadeau"
                placeholder={"Entrez l'URL du cadeau"}
                value={values.giftUrl}
                onChangeText={handleChange("giftUrl")}
                error={touched.giftUrl && errors.giftUrl}
                keyboardType="url"
              />
              <FormInput
                label="Détails du cadeau"
                placeholder={"Taille, pointure, couleur, etc"}
                value={values.giftDetails}
                onChangeText={handleChange("giftDetails")}
                error={touched.giftDetails && errors.giftDetails}
                required={false}
              />
              <FormInput
                label="Prix du cadeau"
                placeholder={"Entrez le prix du cadeau"}
                value={values.giftPrice}
                onChangeText={handleChange("giftPrice")}
                error={touched.giftPrice && errors.giftPrice}
                keyboardType="numeric"
              />
              <FormButton title={btnTxt} onPress={handleSubmit} />
            </View>
          )}
        </Formik>
      )}
    </>
  );
}

const styles = StyleSheet.create({
  form: {
    width: "80%",
    rowGap: 15,
    alignItems: "center",
    justifyContent: "center",
  },
});

export default GiftForm;

版本:

"formik": "^2.4.3", "react": "18.2.0", "react-native": "0.72.6",

react-native formik
1个回答
0
投票

您正在从 API 中选择现有值。您用它来预先填写表格。该日期存储在父组件中,即 EditGiftScreen.js

 useEffect(() => {
    // Faites une requête à votre API pour récupérer les détails du cadeau
    api
      .get(`/gifts/${giftId}`) // Assurez-vous que l'URL est correcte
      .then((response) => {
        setGift(response.data);
        setApiError(null);
      })
      .catch((error) => {
        console.error(error);
        setApiError(
          `Une erreur est survenue lors de la récupération du cadeau du cadeau, veuillez écrire à ${process.env.CONTACT_EMAIL}.`
        );
      });
  }, [giftId]);

我认为问题在于您传递给初始值的状态。在 api 调用成功并用新数据填充之前。它包含过时的数据,这就是为什么您看到旧数据,然后在毫秒左右更新。

解决方案

在 onSubmit 中,成功提交后将礼物重置为其初始值。我建议您实现加载和成功标志,以便您可以更好地跟踪此状态。

  const handleEditGift = async (values) => {
    try {
      await api.patch(`/gifts/${giftId}`, {
        name: values.giftName,
        url: values.giftUrl,
        details: values.giftDetails,
        price: parseFloat(values.giftPrice),
      });
      setApiError(null);
      setGift(null); // ADD THIS LINE
      if (selectedChild) {
        navigation.navigate("ChildrenList", { currentChild: selectedChild });
      } else {
        navigation.navigate("MyList");
      }
    } catch (error) {
      if (error.response) {
        console.log(error.response.data);
      }
      console.error(error);
      setApiError(
        `Une erreur est survenue lors de la mise à jour du cadeau, veuillez écrire à ${process.env.CONTACT_EMAIL}.`
      );
    }
  };
© www.soinside.com 2019 - 2024. All rights reserved.