Обновление состояния родственного компонента заканчивается бесконечным циклом с использованием useEffect

У меня есть родительский компонент 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
    })
..
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
0
0
18
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны передать values как зависимость useEffect

useEffect(() => {
  props.setChartOptions(calculateOffer(values));
}, [values]);

запускать этот эффект только при изменении values.

В коде без useEffectvalues привязан к предыдущим данным, а не к последним данным, потому что setState в React асинхронен. Это означает, что setValues({ ...values, [prop]: event.target.value }); не сразу обновит ваш values.

Прочитайте больше (Эта ссылка относится к setState в компоненте класса, но она должна быть такой же для useState хука)

Другие вопросы по теме