Как узнать триггер useEffect, чтобы сделать с ним условие?

У меня есть useEffect с двумя состояниями в массиве зависимостей, что-то вроде этого:

const [currentTab, setCurrentTab] = useState('open');
const [searchParams, setSearchParams] = useState('');

 useEffect(() => {
  if (condition) {
    // useEffect logic
    } else {
     return;
 }, [currentTab, searchParams]);

Но я хочу, чтобы это условие применялось только в том случае, если триггером useEffect был currentTab, иначе, если триггером был searchParams, я бы хотел запустить эту логику useEffect без каких-либо условий. Каков наилучший подход к решению этой проблемы?

Я уже пробовал разделить его на два разных useEffects для каждого состояния, чтобы выполнить условие только в одном, но это тоже не сработало, потому что этот способ запускал бы оба useEffects при монтировании компонента, а это не ожидалось.

Что вы подразумеваете под «Я бы хотел запустить эту логику useEffect без каких-либо условий»?

VicenteC 15.05.2024 00:11

Кажется, вам нужно отслеживать prevCurrentTab — с помощью собственной переменной состояния или через useRef, как показывает Дмитрий ниже.

Kevin Ashworth 15.05.2024 00:46

@VicenteC Я имел в виду, что хочу запустить useEffect без оператора if else, чтобы он работал с фактической логикой «// useEffect», которая у меня есть

Joe Hill 15.05.2024 01:31
Поведение ключевого слова "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
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вы можете попробовать использовать useRef, чтобы сохранить предыдущее значение currentTab.

const [currentTab, setCurrentTab] = useState('open');
const [searchParams, setSearchParams] = useState('');
const prevTab = useRef(currentTab);

useEffect(() => {
   isTabNotChanged = currentTab === prevTab.current
   if (isTabNotChanged || condition) {
     // useEffect logic
   }
   prevTab.current = currentTab;
}, [currentTab, searchParams]);

Но я не уверен, что нет способа сделать логику компонента более простой. Возможно, есть лучший способ организовать код. Например (не уверен, что вы сможете применить это в своем приложении), вы можете изменить свойство key компонента, что приведет к повторному рендерингу компонента с нуля.

кстати, это сработало, но я думаю, что с такой ситуацией не должно быть так сложно справиться, например... было бы неплохо, если бы React позволял видеть триггер useEffect без необходимости вручную его кодировать вот так

Joe Hill 15.05.2024 20:21

Этого можно добиться, используя один крючок useEffect с условным оператором внутри него. Вы можете проверить, какое состояние изменилось, используя предыдущее значение функции установки useState. Вот пример:

import { useState, useEffect } from 'react';

const [currentTab, setCurrentTab] = useState('open');
const [searchParams, setSearchParams] = useState('');

useEffect(() => {
  const prevCurrentTab = useState[0]; // get the previous value of currentTab
  const prevSearchParams = useState[1]; // get the previous value of searchParams

  if (currentTab !== prevCurrentTab && condition) {
    // useEffect logic when currentTab changes and condition is true
  } else if (searchParams !== prevSearchParams) {
    // useEffect logic when searchParams changes (no condition)
  }
}, [currentTab, searchParams]);`

Таким образом, вы можете применять условную логику только при изменении состояния currentTab и пропускать ее при изменении состояния searchParams.

Примечание. useState[0] и useState[1] используются для доступа к предыдущим значениям currentTab и searchParams соответственно. Это распространенная закономерность при работе с несколькими состояниями в одном крючке useEffect.

Кроме того, обязательно добавьте необходимые зависимости в массив useEffect, чтобы он работал при изменении состояний.

Я собирался предложить другую переменную состояния для отслеживания prevCurrentTab. Обозначение, которое вы используете, для меня ново для этой цели! Вы называете это обычным, но я не вижу его на сайте response.dev, поэтому интересно узнать, хорошо ли он по-прежнему поддерживается в React?

Kevin Ashworth 15.05.2024 00:45

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