Данные из back превращаются в неопределенные, даже если они появляются при их регистрации

#reactjs #undefined #destructuring

#reactjs #не определено #деструктурирование

Вопрос:

Я пытаюсь присвоить значения, которые я получаю из back, объекту initialvalues . Я получаю эти данные, но они превращаются в undefined при назначении их переменным.

 import { Formik, Form } from "formik";
import * as Yup from "yup";
import axios from "axios";
//components
import FormikControl from "../formik/FormikControl";
import Button from "../Button";

const UpdateUserProfile = (props) => {
  const userID = 8; //(state)
  const [myDetails, setMyDetails] = useState([]);

  useEffect(() => {
    const getMyDetails = async () => {
      const url = `http://localhost:5000/allpeople/myDetails/${userID}`;
      const result = await axios.get(url);
      setMyDetails(result.data);
    };
    getMyDetails();

    
  }, []);
  let first_name, last_name, email, logo, phone

  if (myDetails.length) {
    const details = myDetails[0];
   first_name = details.first_name
    console.log('first_name:', first_name) //output: Manon
    
  }
  
  console.log('first_name:', first_name) // output Manon
  let initialValues = {
    first_name: first_name,
    last_name: 'dupont',
    email: 'manondupont@gmail.com',
    phone: '0600000000',
    logo: 'non renseigné',
  };


  const onSubmit = async (values) => {
    console.log("values:", values);
    const url = `http://localhost:5000/users/updateProfile/${userID}`;
    await axios.put(url, values);
  };

  return (
    <div>
      <Formik
        initialValues={initialValues}
        validationSchema={validationSchema}
        onSubmit={onSubmit}
      >
        {(formik) => (
          <Form className="signIn__form">
            <FormikControl
              control="input"
              type="text"
              name="first_name"
              label="Prénom"
            />
            <FormikControl
              control="input"
              type="text"
              name="last_name"
              label="Nom"
            />

             //...

            <Button
              type="submit"
              disabled={!formik.isValid}
              className={"btn btn--round"}
              value={"Modifier mon profil"}
            />
          </Form>
        )}
      </Formik>
    </div>
  );
};

export default UpdateUserProfile;
  

Я получаю значения, которые я присвоил себе (в переменной initialValues), но не значение first_name, хотя я могу его зарегистрировать
форма
при отправке формы first_name не определено. Я не могу понять, почему.
консоль

Комментарии:

1. При первом отображении компонента details имеет значение null. useEffect это асинхронный вызов. Все компоненты React должны иметь возможность отображать, даже если данных там еще нет. Вам нужно обернуть все данные после useEffect in if(myDetails.length > 0) или аналогичной стратегии, чтобы справиться с этим

Ответ №1:

Массив начинается с пустого:

 const [myDetails, setMyDetails] = useState([]);
  

Итак, когда useEffect выполняется изначально, myDetails это пустой массив, так myDetails[0] и есть undefined .

Вы видите, что массив все равно регистрируется, потому что ошибка выдается после запуска useEffect функции (не обратный вызов, переданный useEffect , а вызов useEffect ).

Попробуйте извлечь элементы из массива только после его заполнения, например:

 useEffect(() => {
    // ...
}, []);
if (myDetails.length) {
    const details = myDetails[0]
    const {
        first_name, last_name, email, logo, phone
    } = details;
    // ...
}
  

Поскольку вы пытаетесь использовать результаты в компоненте Formik, установите значение state для параметра initialValues внутри эффекта, а затем визуализируйте компонент Formik только после заполнения значений:

 useEffect(() => {
  axios.get(url)
    .then((result) => {
      setInitialValues(result.data[0])
    }).catch(handleErrors);
}, []);
// ...

return (
    <div>
      { !initialValues ? null : <Formik
        // ...
  

Комментарии:

1. Это работает. Спасибо! Однако, как я могу получить данные за пределами области if. Я пытаюсь return details , но это не работает.

2. См. Редактирование, вам необходимо использовать условный рендеринг для компонента Formik

3. Большое вам спасибо!!!!!!!! Это работает. Ты сделал мой день. Я боролся целую вечность.

Ответ №2:

Вы можете попробовать сопоставление, myDetails array чтобы получить значения объекта внутри массива. Например

 const details = myDetails.map(detail => detail)
  

Затем вы можете разрушить значения следующим образом,

 {name, email,...} = details
  

Ответ №3:

Добавление оператора OR вы можете вернуть пустой объект в случае, если details не определено, пусто:

 const {
  first_name, last_name, email, logo, phone
} = details || {};