#javascript #reactjs #use-state
Вопрос:
import { useEffect, useState } from "react";
export default function App() {
const [criteria, setCriteria] = useState({});
const handleCriteriaChange = (values) => {
// setCriteria(prevCriteria => ({
// ...prevCriteria,
// ...values
// }))
setCriteria({
...criteria,
...values
});
};
useEffect(() => {
setTimeout(() => {
handleCriteriaChange({
courses: ["calculus", "psychology"]
});
}, 1000);
setTimeout(() => {
handleCriteriaChange({
type: "manual"
});
}, 5000);
setTimeout(() => {
handleCriteriaChange({
termLengths: [14, 7]
});
}, 10000);
// eslint-disable-next-line
}, []);
console.log({ criteria: JSON.stringify(criteria) });
return (
<div className="App">
<h1>Hello CodeSandbox {JSON.stringify(criteria)}</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
Я добавил логику для обновления объекта состояния с помощью разных ключей с интервалом в 5 секунд между каждым обновлением. И я ожидал, что все ключевые значения появятся в объекте состояния, но отображается только последнее обновление состояния. Почему я не могу получить все добавленные значения ключа:? Даже если есть пакетирование состояний, они обновляют состояние с помощью разных ключей.
Комментарии:
1. У вас есть устаревшая ссылка на ваше состояние
handleCriteriaChange
, заменяющая состояние старым состоянием.2. Как это состояние может быть несвежим
handleCriteriaChange
?3. У
useEffect
вас есть только ссылка на первоеhandleCriteriaChange
, которое было создано, внутри которой находится устаревшая ссылка на первое состояние.
Ответ №1:
проблема с вашей функцией состояния обновления handleCriteriaChange
. переменная criteria
пуста в useEffect
функции и при ее использовании или назначении. вы должны использовать значение предыдущего состояния при обновлении состояния.
import React from 'react';
import { useEffect, useState } from 'react';
export default function App() {
const [criteria, setCriteria] = useState({});
const handleCriteriaChange = (values) => {
setCriteria(prev=> ({
...prev,
...values,
}));
};
useEffect(() => {
setTimeout(() => {
handleCriteriaChange({
courses: ['calculus', 'psychology'],
});
}, 1000);
setTimeout(() => {
handleCriteriaChange({
type: 'manual',
});
}, 5000);
setTimeout(() => {
handleCriteriaChange({
termLengths: [14, 7],
});
}, 10000);
// eslint-disable-next-line
}, []);
console.log({ criteria: JSON.stringify(criteria) });
return (
<div className="App">
<h1>Hello CodeSandbox {JSON.stringify(criteria)}</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
Комментарии:
1. Это сработало для меня. Отличный ответ….