Запуск функции React useEffect при изменении пустого массива

#javascript #arrays #reactjs #react-router #next.js

#javascript #массивы #reactjs #react-маршрутизатор #next.js

Вопрос:

Приложение react, над которым я работаю, запускает userEffect функцию, если значение prop изменяется с пустого массива на другой пустой массив.

Я получаю параметры запроса со страницы и передаю их в компоненте, который повторно отображает, если какой-либо из массива параметров запроса изменяется. Но проблема в том, что useEffect функция запускает и повторно отображает компонент, даже если массив параметров запроса изменился с [] на [] .

Я знаю это [] !== [] , возможно, именно это вызывает проблему. Но есть ли способ, которым приложение может предотвратить запуск функции useEffect в первую очередь?

Вот демонстрация codesandbox:https://codesandbox.io/s/vibrant-greider-qgjgs?file=/src/App.js

Комментарии:

1. Неясно, что именно вы пытаетесь сделать. Когда именно вы хотите useEffect запустить?

2. @jered , просто не хочу запускать ее, если реквизит изменится с [] на []

3. почему бы просто не использовать if-else внутри useEffect? Это все равно вызовет функцию, но функция все еще может решить, что делать

4. @MuhammedB. Айдемир, может быть, я мог бы использовать оператор if для проверки длины. что произойдет, если параметр запроса изменится с ['some-data'] to []`. Как вы с этим справляетесь?

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

Ответ №1:

вы назначаете новую ссылку на тест, следовательно, он запускает обновление.

вы должны переназначить тот же массив и манипулировать в нем.

    const handleClick = () => {
   const arr = test
    setTest(arr);
  };
  

Комментарии:

1. это может сработать в этом конкретном сценарии. Но что мне делать, если массив из параметра запроса?

2. она также должна работать там. Поскольку параметр запроса собирается изменить ваш массив. Это будет обработано useEffect. И в useEffect она сработает автоматически, когда получит новые данные.

3. Я имел в виду, что arrray поступает прямо из параметра запроса. Я ничего не делаю с этим массивом, просто проверяю, отличается ли массив

4. можете ли вы привести пример вашего подхода, в котором я могу помочь.

Ответ №2:

Вы можете либо создать свой собственный пользовательский хук, который проверяет глубокое равенство для каждого из элементов массива зависимостей, либо использовать что-то вроде use-deep-compare-effect

Ответ №3:

В дополнение к ответу выше, вы также можете использовать React.memo как способ проверки сравнения между предыдущими реквизитами и новыми реквизитами. Если ваш реквизит несколько сложен, вы, вероятно, можете добавить Lodash поверх него.

Комментарии:

1. не работает. Вот демонстрация: codesandbox.io/s/affectionate-currying-fkbh1?file=/src/Test.js

2. Вы говорите о реквизитах на <Test /> ? Вы ничего не передаете этому компоненту, но это не имеет большого значения для проблемы, с которой вы столкнулись. Ваш setTest повторно отобразит компонент приложения, который впоследствии повторно отобразит свой дочерний компонент.