#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
inif(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 || {};