tgoop.com/startpoint_dev/66
Create:
Last Update:
Last Update:
Server Components и Server Actions. Часть 2.
В предыдущем посте мы поговорили про Server Components, а сегодня рассмотрим Server Actions.
Ранее, когда мы рассказывали про новые хуки React, мы уже посмотрели на примерах, как можно работать с серверными экшенами в сочетании с хуком useActionForm (вот здесь можно почитать подробнее).
Но на самом деле нам не обязательно использовать новые хуки React или даже серверные компоненты для работы с серверными экшенами.
Посмотрим на пример простого компонента со списком товаров. Он также осуществляет поиск товаров по строке через внешнее API, в которое передается поисковый запрос:
'use client';
import { useState } from 'react';
import { search } from './searchAction';
export function SearchedList({ fetchInitialData }: Props) {
const [searchText, setSearchText] = useState('');
const [data, setData] = useState<SearchResponce | null>(null);
const handleChangeSearch = (event) => setSearchText(event.target.value);
const handleClick = async () => {
const result = await search(searchText);
setData(result);
};
return (
<section>
<div>
<input name="search" onChange={handleChangeSearch} value={searchText} />
<button type="submit" onClick={handleClick}>Search</button>
</div>
{data && (
<ul>
{data.products.map((product) => (
...
))}
</ul>
)}
</section>
);
}
Здесь search выглядит как обычная функция, но на самом деле это серверный экшен. Делает её таким директива 'use server'.
'use server';
export const search = async (query: string) => {
console.log('[SearchedList] Server Action');
const data = (await fetch(`https://dummyjson.com/products/search?limit=10&q=${query}`).then((res) => res.json()));
return data;
};
В чем отличия серверного экшена
🔹 Серверный экшен выполняется только на сервере.
В нашем примере вывод в консоль '[SearchedList] Server Action' будет выполнен на сервере. Если бы это была обычная функция, то этот вывод был бы в консоли браузера.
🔹 Общение между клиентом и сервером для серверных экшенов происходит посредством специальных API-зпросов.
При клике на кнопку Search в браузере будет происходить POST-запрос на тот же URL, на котором мы находимся (локально это http://localhost:3000/).
В ответ придут данные в специальном формате:
0:["$@1",["development",null]]
1:{"products":[{"id":101,"title":"Apple AirPods Max Silver","description":"The...
Таким образом нам не нужно добавлять новый эндпоинт в API, в коде мы получаем эти данные, как если бы мы просто вызвали какую-то функцию. При этом внутри функции search вместо запроса к внешнему API может быть запрос на чтение из файла или напрямую из базы данных.
Кроме этого мы можем передать promise из серверного экшена как пропс в наш клиентский компонент:
import { search } from './searchAction';
export function SearchedList() {
const fetchInitialData = search('');
return (
<Suspense fallback="Loading...">
<SearchedListBase fetchInitialData={fetchInitialData} />
</Suspense>
);
}
И дальше использовать новый метод use для того, чтобы дождаться результат его выполнения и применить как initialValue в хуке useState:
type Props = {
fetchInitialData: Promise<SearchResponce>;
};
export function SearchedList({ fetchInitialData }: Props) {
const initialData = use(fetchInitialData);
const [data, setData] = useState<SearchResponce>(initialData);
...
}
📂 Подробнее примеры можно посмотреть в нашем репозитории на GitHub.
Я считаю, что появление Server Components и Server Actions приближает ту эпоху, когда фронтендеру нужно уметь работать не только в среде браузера, но и быть немного бэкендером. Новые инструменты, с одной стороны, предоставляют много новых возможностей, в том числе и для оптимизации. Но как и со всеми новыми технологиями, нужно знать, как их готовить.
✍️ А как cчитаете вы - поделитесь в комментариях, что думаете о развитии React в сторону серверных компонетов и экшенов!
BY Настя Котова // Frontend & Node.js
Share with your friend now:
tgoop.com/startpoint_dev/66
