В общем, что лучше использовать один или несколько хуков useEffect в одном компоненте?

У меня есть некоторые побочные эффекты, которые нужно применить в моем компоненте реакции, и я хочу знать, как их организовать:

  • как одноразовое использование
  • или несколько useEffects

Что лучше с точки зрения производительности и архитектуры?

Это, вероятно, имеет значение в зависимости от вашего варианта использования, но я собираюсь отредактировать ваш вопрос, чтобы прояснить, что это касается общих советов.

Pureferret 09.11.2021 14:34
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
204
1
123 307
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Шаблон, которому вам нужно следовать, зависит от вашего варианта использования.

Первый: У вас может быть ситуация, когда вам нужно добавить прослушиватель событий во время первоначального монтирования и очистить их при размонтировании, а также другой случай, когда конкретный слушатель необходимо очистить и повторно добавить при изменении свойства.

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

useEffect(() => {
   // adding event listeners on mount here
   return () => {
       // cleaning up the listeners here
   }
}, []);

useEffect(() => {
   // adding listeners everytime props.x changes
   return () => {
       // removing the listener when props.x changes
   }
}, [props.x])

Второй: Вам необходимо инициировать вызов API или какой-либо другой побочный эффект, когда какое-либо состояние или свойства изменяются из определенного набора. В таком случае было бы лучше использовать один useEffect с соответствующими зависимостями для мониторинга.

useEffect(() => {
    // side effect here on change of any of props.x or stateY
}, [props.x, stateY])

Третий: Вам нужен отдельный побочный эффект для разных наборов изменений. В таком случае разделите соответствующие побочные эффекты на разные useEffect.

useEffect(() => {
   // some side-effect on change of props.x
}, [props.x])

useEffect(() => {
   // another side-effect on change of stateX or stateY 
}, [stateX, stateY])

как насчет золотой середины между примерами Второй и Третий выше ?: у вас есть логика, которая запускается при изменении подмножества состояний / реквизитов, но у каждого есть отдельная логика, которая должна выполняться в дополнение к некоторому общему коду, который необходимо запустить? Вы бы не стали использовать [] (потому что это все еще подмножество состояний / свойств, для которых вы ожидаете изменений), но вы также хотели бы повторно использовать код. Вы используете отдельный useEffects и помещаете общий код в функцию, которую каждый из них вызывает отдельно?

ecoe 25.08.2019 20:22

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

hakazvaka 20.09.2019 12:17

Всегда ли они запускаются в порядке их определения? т.е. сначала всегда вызывается эффект1, затем эффект2?

computrius 04.06.2020 22:58

@computrius да, React will apply every effect used by the component, in the order they were specified.

August Janse 17.11.2020 07:49

Что, если у меня есть несколько эффектов componentDidMount (пустой массив []), но они делают разные вещи? я должен использовать их в одном useEffect или в нескольких?

Dror Bar 16.03.2021 10:08

Вы должны использовать несколько эффектов для отдельные проблемы как предложено reactjs.org.

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

Pureferret 09.11.2021 14:41

Хотя эта ссылка может дать ответ на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если ссылка на страницу изменится. - Из обзора

camille 10.11.2021 04:46

Идеально иметь отлично для множественного useEffect.

Вот как выглядит одна из моих настроек:

/*
 * Backend tags list have changed add the changes if needed
 */
useEffect(() => {
    setTagsList(setTagsAdded);
}, [setTagsAdded]);

/*
 * Backend files have changed add the changes if needed
 */
useEffect(() => {
    for (let i = 0; i < changedFilesMeta.length; i += 1) {
        // Is the list item value changed
        if (changedFilesMeta[i].id === currentEditableFile.id) {
            unstable_batchedUpdates(() => {
                setTags(changedFilesMeta[i].tags ? changedFilesMeta[i].tags : []);
            });
        }
    }
}, [changedFilesMeta]);

/*
 * Reset when user select new files using the filepicker
 */
useEffect(() => {
    if (setNewFiles.length > 0) {
        unstable_batchedUpdates(() => {
            setCurrentFile(null);
            setDescription('');
            setTitle('');
            setTags([]);
        });
    }
}, [setNewFiles]);

/*
 * User selecet to edit a file, change to that file
 */
useEffect(() => {
    // When user select a file to edit it
    if (currentEditableFile && currentEditableFile !== theCurrentFile) {
        setCurrentFile(currentEditableFile);
        unstable_batchedUpdates(() => {
            setDescription(currentEditableFile.description);
            setTitle(currentEditableFile.title);
            setTags(currentEditableFile.tags);
        });
    }
}, [currentEditableFile]);

не могли бы вы добавить еще немного своего кода, чтобы прояснить, какой бит состояния обновляется setTags? setTagsAdded - это функция или объект? Также как вы убедились, что «производительность и архитектура» лучше, чем один большой useEffect?

Pureferret 09.11.2021 14:33

Я не думаю, что включение этого кода, особенно вне контекста, полезно или имеет отношение к вопросу.

Bricky 09.11.2021 19:00

@Bricky, несмотря ни на что, удаление всего кода И добавление цитаты слишком сильно меняет ответ, чтобы его оправдать

Pureferret 09.11.2021 19:46

Цитата находится в соответствующем разделе по ссылке. Простое включение ссылки - легкий ответ.

Bricky 10.11.2021 22:37

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