Как разрешить useEffect запускаться только один раз, как в React 18?

Мне нужно получить изображение в кодировке base64 в useEffect, а затем создать тег изображения на странице. Мой (упрощенный) код выглядит следующим образом:

const App => {
    const [image, SetImage] = useState('');
    useEffect(
        async function fetchImage() {
            //...
            await response = fetch('API-to-get-base64image');
            SetImage(response);
        }, [])

    return (
        <div><img src = {image}/> </div>
    )
}

Мне нужно запустить этот useEffect только один раз, потому что изображение большое, а его запуск дважды замедляет загрузку страницы. Но, как указано во многих сообщениях, подобных этому: Как вызвать функцию загрузки с помощью React useEffect только один раз, начиная с React 18, установка зависимости в виде пустого массива больше не дает такого эффекта. Интересно, какое новое решение позволяет этому useEffect запускаться только один раз?

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

Ответы 1

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

У меня была такая же проблема, пока я не прочитал раздел «Глубокое погружение» в Извлечение данных с помощью эффектов в документации React.

Соответствующий бит:

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

  • Если вы используете фреймворк, используйте его встроенный механизм получения данных. Современные фреймворки React имеют интегрированные механизмы получения данных, которые эффективны и не страдают от вышеперечисленных недостатков.
  • В противном случае рассмотрите возможность использования или создания кэша на стороне клиента. Популярные решения с открытым исходным кодом включают React Query, useSWR и React Router. 6,4+. Вы также можете создать свое собственное решение, и в этом случае вы будете использовать эффекты «под капотом», а также добавить логику для дедупликации запросов. кэширование ответов и избежание сетевых водопадов (путем предварительной загрузки данных или повышение требований к данным для маршрутов).

В моем случае useSWR уже был частью зависимостей проекта, и, судя по примеру, его довольно просто использовать:

import useSWR from 'swr'
 
function Profile() {
  const { data, error, isLoading } = useSWR('/api/user', fetcher)
 
  if (error) return <div>failed to load</div>
  if (isLoading) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

Впоследствии я убедился, что Извлечение происходит только один раз, счастливых дней...

Итак, для вашего кода это будет что-то вроде:

import useSWR from 'swr'

const App => {
    const [image, SetImage] = useState('');

    async function fetchImage(url) {
        //...
        await response = fetch(url);
        SetImage(response);
    }

    const { data, error, isLoading } = useSWR('API-to-get-base64image', fetchImage)

    return (
        <div><img src = {image}/> </div>
    )
}

Спасибо за ваше решение. На самом деле я нашел очень простой способ сделать это. Просто проверьте, пусто ли изображение в первой строке внутри useEffect, и немедленно вернитесь, если оно уже имеет значение.

SamTest 25.06.2024 21:10

Я не уверен, что проверка состояния всегда будет работать. Если React попытается смонтировать компонент во второй раз, пока ваш запрос находится в работе (вероятно, это скорее проблема с медленным API, чем с изображением), он выдаст ошибку. второй запрос.

dain 25.06.2024 23:54

Что ж, в моем реальном и гораздо более сложном коде я бы присвоил значение другой переменной, прежде чем выполнять выборку. И что я на самом деле проверил, так это значение этой переменной. Поскольку это не выборка, она не будет «в полете». Да, я согласен с вами, что если бы это был код, который я разместил выше, возможно, он мог бы запуститься дважды. Однако в этом случае, я думаю, мы все равно можем установить дозорную переменную, чтобы предотвратить ее второй запуск. Возможно, это не самый достойный способ сделать это, но выполнить работу просто и быстро.

SamTest 26.06.2024 02:53

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