Резервные повторные триггеры React

У меня есть изображение, которое я беру из конечной точки API. По какой-то причине я импортирую компонент изображения внутри Suspense с запасным вариантом. Проблема в том, что каждый раз, когда выполняется useState или useEffect, отображается запасной вариант Suspense. Есть ли способ предотвратить отображение резервного варианта Suspense после первого рендеринга или при кэшировании изображения?

 export async function AvatarIcon({ id }: { id: string }) {
  const avatarIcon = await getAvatarIcon(id)

  return (
    <div className = "">
      <Image
        src = {`data:image/png;base64, ${avatarIcon}`}
        height = {40}
        width = {40}
        className = "relative z-0 h-full w-16"
        alt = "Avatar Icon"
      ></Image>
    </div>
  )
}

Другой компонент, который я использую Suspense:

<div>
  <Suspense fallback = {<div></div>}>
    <AvatarIcon id = {user.id} />
  </Suspense>
</div>

Используете ли вы компоненты React Server или построенную на нем платформу? Я думаю, да, поскольку ваш пример полностью взорвется на клиентском компоненте, поскольку компоненты там не могут быть асинхронными.

adsy 17.06.2024 02:54

Да, я использую nextJs. Есть ли другой способ сделать это?

soger 17.06.2024 09:24

И просто убедиться, что файл AvatarIcon нигде не делает use client?

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

Ответы 2

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

fallback работает, потому что значение свойства loading по умолчанию — «ленивый». из документов

Поведение загрузки изображения. По умолчанию ленивый.

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

Когда захотите, немедленно загрузите изображение.

если вы измените loading = "eager", это может сработать (я не проверял), потому что компонент уже загружен и готов к рендерингу. Компонент Suspense показывает свое резервное содержимое только тогда, когда обернутый компонент не готов к рендерингу.

Но я думаю, что установка «жаждущего» параметра внутри Suspense не имеет смысла, поскольку Suspense специально разработан для обработки компонентов, загружающихся асинхронно.

  • поскольку вы извлекаете изображение, возможно, вам следует кэшировать эту выборку с помощью useSwr или нестабильного_кэша

  • поскольку вы получаете изображение из API, в next.js есть опция файла загрузчика. например, для облачности

    // Демо: https://res.cloudinary.com/demo/image/upload/w_300,c_limit,q_auto/turtles.jpg экспортировать функцию по умолчанию cloudinaryLoader({ src, width,quality }) { const params = ['f_auto', 'c_limit', w_${width}, q_${quality || 'auto'}] вернись https://example.com/${params.join(',')}${src} }

в этом файле загрузчика вы можете проверить Поведение кэширования :

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

Изображения оптимизируются динамически по запросу и сохраняются в Каталог /cache/images. Оптимизированный файл изображения будет подается для последующих запросов до истечения срока действия. Когда сделан запрос, который соответствует кэшированному файлу, но срок действия которого истек, срок действия файла с истекшим сроком действия изображение сразу становится устаревшим. Затем изображение снова оптимизируется в фоновом режиме (также называемая повторной проверкой) и сохраняется в кеше с новым сроком годности.

Статус кэша изображения можно определить, прочитав значение заголовок ответа x-nextjs-cache. Возможные значения: следующий:

  • MISS - пути нет в кеше (происходит максимум один раз, при первом посещении)
  • УСТАРЕВШИЙ — путь находится в кеше, но время повторной проверки превысило время, поэтому он будет обновлен в фоновом режиме.
  • HIT — путь находится в кеше и не превысил время повторной проверки. Срок действия (или, скорее, максимальный возраст) определяется либо параметром конфигурация минимальногоCacheTTL или исходный образ Cache-Control заголовок, в зависимости от того, какой из них больше. В частности, значение максимального возраста Используется заголовок Cache-Control. Если найдены оба s-maxage и max-age, тогда предпочтительнее s-maxage. Максимальный возраст также передается на любой последующие клиенты, включая CDN и браузеры.

Вы можете настроить minimumCacheTTL, чтобы увеличить продолжительность кэша. когда восходящий образ не включает заголовок Cache-Control или значение очень низкое. Вы можете настроить размер устройств и размер изображений для уменьшить общее количество возможных генерируемых изображений. Ты можешь настроить форматы, чтобы отключить несколько форматов в пользу одного формат изображения.

Большое спасибо за подробный ответ. Нетерпеливый вариант и нестабильный кэш не сработали. Однако useSwr делает свою работу. Теперь все работает правильно.

soger 19.06.2024 23:38
const fetcher = (url: string, id: string) => {
  const urlWithQuery = ${url}/${id}/icon
  return fetch(urlWithQuery).then((res) => res.json())
}

const { data, error, isLoading } = useSWR(
  ['/api/avatar', id],
  ([url, id]) => fetcher(url, id),
  {
    revalidateOnFocus: true
  }
)

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