В разделе «Паттерны и лучшие практики» говорится: «рекомендуется получать данные на сервере с помощью серверных компонентов». Пока речь идет о запросах без авторизации юзера, всё хорошо. Но если запрос предполагает авторизацию пользователя, начинаются проблемы.
Например, мы получаем данные профиля пользователя в серверном компоненте (при первом рендере страницы) с помощью запроса на REST API стороннего сервера. Для этого мы отправляем стороннему серверу accessToken, прочитанный из куков пользователя. Если сервер вернул нам 401 (т.е. токен устарел и требует обновления), мы тут же с помощью refreshToken получаем новую пару accessToken и refreshToken, но не имеем возможности записать эти новые токены в куки (поскольку запись в куки возможна только в route handlers, server actions и middleware). На всякий случай уточню, что запрос данных при первом рендере страницы не является server action, поскольку не вызывается в результате действия пользователя (например, отправки формы с атрибутом action, в который передан server action).
Новые токены можно было бы записать в куки в middleware, но на стадии перехвата запроса в middleware мы еще не знаем, вернет ли нам сторонний сервер 401 (поскольку перехват происходит раньше). Казалось бы, в middleware можно запрашивать новые токены вообще при каждом запросе, но переписывать куки мы можем лишь в заголовках ответа, а не запроса, поэтому новые токены будут записаны в куки лишь при получении ответа пользователем, а сам текущий запрос будет осуществлен со старыми куками (а, значит, и со старым accessToken).
Судя по тематическим ресурсам, сообщество сейчас не очень понимает, как быть с этой проблемой.
По поводу useFormState: похоже, что от него собираются отказаться в пользу нового хука useActionState.
Причина в том, что название хука useFormState может сбивать с толку, поскольку на самом деле он возвращает не состояние конкретной формы, а состояние переданного в хук действия (action). Имя нового хука уберет эту путаницу.
Кроме того, useActionState будет возвращать третий параметр – pending (сейчас для его получения нужно использовать useFormStatus).
Не могли бы вы подробнее объяснить этот момент: «поскольку стриминг является серверным, он не влияет на SEO»?
Как я понимаю, поисковики сначала получают пустой макет (бесполезный для SEO) и после этого должны дождаться, когда подгрузятся обернутые в <Suspense> чанки. Вроде бы современные поисковики должны справиться с js-подгрузкой контента, но все-таки корректно ли говорить, что это вообще не влияет на SEO?
Я иногда делаю на своих мобильных сайтах появляющуюся по обратному скроллу шапку – это мне кажется привычной для пользователя механикой. Но чтобы не бесить людей шапка появляется, во-первых, не сразу – для этого нужно проскроллить вверх какое-то расстояние на случай, если пользователь просто хочет перечитать предыдущие строки текста; а, во-вторых, шапка не падает сверху рывком, закрывающим верхние строки, а появляется плавно, со скоростью скролла. Это мне кажется разумным компромиссом.
В разделе «Паттерны и лучшие практики» говорится: «рекомендуется получать данные на сервере с помощью серверных компонентов». Пока речь идет о запросах без авторизации юзера, всё хорошо. Но если запрос предполагает авторизацию пользователя, начинаются проблемы.
Например, мы получаем данные профиля пользователя в серверном компоненте (при первом рендере страницы) с помощью запроса на REST API стороннего сервера. Для этого мы отправляем стороннему серверу accessToken, прочитанный из куков пользователя. Если сервер вернул нам 401 (т.е. токен устарел и требует обновления), мы тут же с помощью refreshToken получаем новую пару accessToken и refreshToken, но не имеем возможности записать эти новые токены в куки (поскольку запись в куки возможна только в route handlers, server actions и middleware). На всякий случай уточню, что запрос данных при первом рендере страницы не является server action, поскольку не вызывается в результате действия пользователя (например, отправки формы с атрибутом action, в который передан server action).
Новые токены можно было бы записать в куки в middleware, но на стадии перехвата запроса в middleware мы еще не знаем, вернет ли нам сторонний сервер 401 (поскольку перехват происходит раньше). Казалось бы, в middleware можно запрашивать новые токены вообще при каждом запросе, но переписывать куки мы можем лишь в заголовках ответа, а не запроса, поэтому новые токены будут записаны в куки лишь при получении ответа пользователем, а сам текущий запрос будет осуществлен со старыми куками (а, значит, и со старым accessToken).
Судя по тематическим ресурсам, сообщество сейчас не очень понимает, как быть с этой проблемой.
По поводу useFormState: похоже, что от него собираются отказаться в пользу нового хука useActionState.
Причина в том, что название хука useFormState может сбивать с толку, поскольку на самом деле он возвращает не состояние конкретной формы, а состояние переданного в хук действия (action). Имя нового хука уберет эту путаницу.
Кроме того, useActionState будет возвращать третий параметр – pending (сейчас для его получения нужно использовать useFormStatus).
const [state, action, isPending] = useActionState(formAction);
…
<form action={action}>
Спасибо за статью!
Не могли бы вы подробнее объяснить этот момент: «поскольку стриминг является серверным, он не влияет на SEO»?
Как я понимаю, поисковики сначала получают пустой макет (бесполезный для SEO) и после этого должны дождаться, когда подгрузятся обернутые в <Suspense> чанки. Вроде бы современные поисковики должны справиться с js-подгрузкой контента, но все-таки корректно ли говорить, что это вообще не влияет на SEO?
Я иногда делаю на своих мобильных сайтах появляющуюся по обратному скроллу шапку – это мне кажется привычной для пользователя механикой. Но чтобы не бесить людей шапка появляется, во-первых, не сразу – для этого нужно проскроллить вверх какое-то расстояние на случай, если пользователь просто хочет перечитать предыдущие строки текста; а, во-вторых, шапка не падает сверху рывком, закрывающим верхние строки, а появляется плавно, со скоростью скролла. Это мне кажется разумным компромиссом.