Реагировать useEffect, как обновлять данные, если два разных массива зависимостей обновляются одновременно

Итак, у меня есть два разных массива useEffect и зависимостей.

 const [dateFilterSort, setDateFilterSort] = useState({
    queryText: initialQueryText(params.sortName),
    cardText: initialCardText(params.sortName),
    start: params.startDate
      ? moment(params.startDate).startOf('day').toDate()
      : undefined,
    end: params.endDate
      ? moment(params.endDate).endOf('day').toDate()
      : undefined,
  });

 useEffect(() => {
    if (params.endDate) {
      setDateFilterSort({
        ...dateFilterSort,
        end: moment(params.endDate).endOf('day').toDate(),
      });
    }
  }, [params.endDate]);

  useEffect(() => {
    if (params.startDate) {
      setDateFilterSort({
        ...dateFilterSort,
        start: moment(params.startDate).startOf('day').toDate(),
      });
    }
  }, [params.startDate]);

Проблема здесь в том, что params.endDate и params.startDate обновляются одновременно. Таким образом, dateFilterSort.start обновляется правильно, но, поскольку dateFilterSort.end выше, dateFilterSort.end был перезаписан вторым useEffect.

Есть ли способ решить эту проблему?

Я подумал, что могу поставить два useEffect, как показано ниже.

    useEffect(() => {
      if (params.startDate) {
        setDateFilterSort({
          ...dateFilterSort,
          start: moment(params.startDate).startOf('day').toDate(),
        });
      }
      if (params.endDate) {
        setDateFilterSort({
          ...dateFilterSort,
          end: moment(params.endDate).endOf('day').toDate(),
        });
      }
    }, [params.startDate, params.endDate]);

что вызвало бесконечный цикл...

Кроме того, просто чтобы посмотреть, смогу ли я обновить params.end, я использую setTimeout, но снова вызываю бесконечный цикл....

 useEffect(() => {
    if (params.endDate) {
      setTimeout(() => {
        setDateFilterSort({
          ...dateFilterSort,
          end: moment(params.endDate).endOf('day').toDate(),
        });
      }, 500);
    }
  }, [params.endDate]);

  useEffect(() => {
    if (params.startDate) {
      setDateFilterSort({
        ...dateFilterSort,
        start: moment(params.startDate).startOf('day').toDate(),
      });
    }
  }, [params.startDate]);

Является ли params переменной состояния или реквизитом?

sebasaenz 04.04.2022 23:09

@sebasaenz params — это состояние. Я добавил, как выглядит состояние Спасибо.

tomo1127 04.04.2022 23:13

вы не должны копировать состояние или производное состояние

よつば 05.04.2022 00:24
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
29
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Недавно у меня была похожая проблема. В моем случае второй сеттер перезаписывал первый.

Хорошее решение, которое я придумал, заключалось в том, чтобы сначала сделать необходимые изменения локально, а затем только один раз установить состояние:

useEffect(() => {
  // Choose your favorite copy technique,
  // I'll go with spread operator for simplicity
  const dateFilterSortCopy = { ...dateFilterSort }
  
  if (params.startDate) {
    dateFilterSortCopy.startDate = moment(params.startDate).startOf('day').toDate()
  }
  
  if (params.endDate) {
    dateFilterSortCopy.endDate = moment(params.startDate).startOf('day').toDate()
  }

  setDateFilterSort(dateFilterSortCopy);
}, [params.startDate, params.endDate]);

Это также избавляет от ненужных повторных рендеров.

Большое спасибо! это решило мою проблему! У меня есть быстрый вопрос относительно вашего кода. последняя часть setDateFilterSort({...dateFilterSortCopy}); этого не может быть setDateFilterSort({dateFilterSortCopy}); ? нам нужен оператор спреда?

tomo1127 05.04.2022 00:12

На самом деле должно быть setDateFilterSort(dateFilterSortCopy). Только что отредактировал, хороший улов!

sebasaenz 05.04.2022 00:16

Я пробовал без оператора распространения и не работал. Так что в некоторых случаях может понадобиться его использовать. Но все равно большое спасибо!

tomo1127 05.04.2022 00:23

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