#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
повторно отобразит компонент приложения, который впоследствии повторно отобразит свой дочерний компонент.