У меня есть родительский компонент PlannerWrapper
, у которого есть дочерние компоненты PlannerChart
, которые возвращают экземпляр ApexChart и отображают его в DOM, и еще один дочерний компонент PlannerTools
, который принимает некоторые входные данные формы и обновляет существующий экземпляр диаграммы.
Я хочу всегда обновлять диаграмму при изменении ввода формы, который каким-то образом работает, но использует не последние измененные данные, а вместо этого предыдущее состояние. Я думаю, это потому, что у меня есть props.setChartOptions(calculateOffer(values))
внутри stateHandler.
Когда я интегрирую useEffect
, чтобы решить эту проблему, я получаю бесконечный цикл прямо при загрузке страницы... почему и как это исправить?
// PlannerWrapper
const PlannerWrapper = () => {
// Create option state for chart
const [chartOptions, setChartOptions] = useState({
options: {
...
return (
<div className="wrapper w-6/6 h-full flex bg-dotted bg-sx-white">
<div className="left-wrapper w-3/6 h-full p-8 pr-0 flex flex-col justify-between">
<div className="chart-wrapper w-full h-48p bg-sx-white-plain rounded-2xl shadow-sx-shadow">
<PlannerChart chartOptions={chartOptions}/>
</div>
</div>
<PlannerTools setChartOptions={setChartOptions}/>
</div>
)
}
// PlannerTools
import {calculateOffer} from "./utils";
const PlannerTools = (props) => {
const handleChange = (prop) => (event) => {
if(prop === 'date') {
return setValues({ ...values, [prop]: event });
}
setValues({ ...values, [prop]: event.target.value });
console.log('test')
// Re-Run calculations
props.setChartOptions(calculateOffer(values)) // <--- This should run once after the new state is available
};
...
// PlannerTools with useEffect
const PlannerTools = (props) => {
..
const handleChange = (prop) => (event) => {
if(prop === 'date') {
return setValues({ ...values, [prop]: event });
}
setValues({ ...values, [prop]: event.target.value });
};
useEffect(() => {
props.setChartOptions(calculateOffer(values)) // <-- ends up in an infinite loop right on page load
})
..
Вы должны передать values
как зависимость useEffect
useEffect(() => {
props.setChartOptions(calculateOffer(values));
}, [values]);
запускать этот эффект только при изменении values
.
В коде без useEffect
values
привязан к предыдущим данным, а не к последним данным, потому что setState
в React асинхронен.
Это означает, что setValues({ ...values, [prop]: event.target.value });
не сразу обновит ваш values
.
Прочитайте больше (Эта ссылка относится к setState
в компоненте класса, но она должна быть такой же для useState
хука)