React Server Components (RSC) — это новая архитектура React, которая позволяет компонентам выполняться на сервере:
// Серверный компонент
async function ServerComponent() {
const data = await fetch('api/data');
return <div>{data.title}</div>;
}
// Клиентский компонент
'use client';
function ClientComponent() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}React Server Components — это революционная архитектура, которая меняет способ создания React приложений! Они позволяют выполнять компоненты на сервере, что даёт множество преимуществ. 🚀
Выполняются на сервере и отправляют готовый HTML:
// app/posts/page.js
async function PostsPage() {
// Выполняется на сервере
const posts = await db.posts.findMany();
return (
<div>
<h1>Посты</h1>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.content}</p>
</article>
))}
</div>
);
}Выполняются в браузере с интерактивностью:
// components/LikeButton.js
'use client';
import { useState } from 'react';
function LikeButton({ postId }) {
const [liked, setLiked] = useState(false);
return (
<button
onClick={() => setLiked(!liked)}
className={liked ? 'liked' : ''}
>
{liked ? '❤️' : '🤍'} Нравится
</button>
);
}// Серверный компонент (по умолчанию)
async function BlogPost({ id }) {
const post = await getPost(id);
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
{/* Клиентский компонент для интерактивности */}
<LikeButton postId={id} />
<Comments postId={id} />
</article>
);
}
// Клиентский компонент
'use client';
function Comments({ postId }) {
const [comments, setComments] = useState([]);
useEffect(() => {
loadComments(postId).then(setComments);
}, [postId]);
return (
<div>
{comments.map(comment => (
<div key={comment.id}>{comment.text}</div>
))}
</div>
);
}// Серверный компонент - 0 KB JavaScript
function ProductList() {
const products = await db.products.findMany();
return (
<div>
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
);
}
// Только интерактивные части отправляются в браузер
'use client';
function AddToCart({ productId }) {
return (
<button onClick={() => addToCart(productId)}>
В корзину
</button>
);
}// Серверный компонент - секретные ключи остаются на сервере
async function UserProfile({ userId }) {
const user = await db.users.findUnique({
where: { id: userId },
select: { name: true, email: true } // Не отправляем пароль
});
return <div>Привет, {user.name}!</div>;
}// Серверный компонент - готовый HTML для поисковиков
async function ArticlePage({ slug }) {
const article = await getArticle(slug);
return (
<>
<Head>
<title>{article.title}</title>
<meta name="description" content={article.excerpt} />
</Head>
<article>
<h1>{article.title}</h1>
<div dangerouslySetInnerHTML={{ __html: article.content }} />
</article>
</>
);
}// app/dashboard/page.js
import { Suspense } from 'react';
function Dashboard() {
return (
<div>
<h1>Панель управления</h1>
<Suspense fallback={<div>Загрузка статистики...</div>}>
<Stats />
</Suspense>
<Suspense fallback={<div>Загрузка графиков...</div>}>
<Charts />
</Suspense>
</div>
);
}
// Медленный серверный компонент
async function Stats() {
const stats = await getStats(); // Медленный запрос
return <div>Статистика: {stats.total}</div>;
}// Серверный компонент передаёт данные клиентскому
async function PostPage({ params }) {
const post = await getPost(params.id);
const user = await getCurrentUser();
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
{/* Передаём данные в клиентский компонент */}
<InteractiveSection
postId={post.id}
userId={user.id}
initialLikes={post.likes}
/>
</div>
);
}
'use client';
function InteractiveSection({ postId, userId, initialLikes }) {
const [likes, setLikes] = useState(initialLikes);
return (
<div>
<button onClick={() => setLikes(likes + 1)}>
👍 {likes}
</button>
</div>
);
}// ❌ Использовать хуки состояния
function ServerComponent() {
const [state, setState] = useState(0); // Ошибка!
return <div>{state}</div>;
}
// ❌ Использовать эффекты
function ServerComponent() {
useEffect(() => {}, []); // Ошибка!
return <div>Content</div>;
}
// ❌ Использовать браузерные API
function ServerComponent() {
const width = window.innerWidth; // Ошибка!
return <div>Width: {width}</div>;
}// ❌ Импортировать серверные модули
'use client';
import { db } from './database'; // Ошибка!
function ClientComponent() {
return <div>Client</div>;
}// ✅ Правильная архитектура
async function ProductPage({ id }) {
const product = await getProduct(id); // Серверный
return (
<div>
<ProductInfo product={product} /> {/* Серверный */}
<AddToCartButton productId={id} /> {/* Клиентский */}
</div>
);
}❌ Неправильно:
// Смешивание серверного и клиентского кода
function Component() {
const [state, setState] = useState(0);
const data = await fetch('/api'); // Ошибка!
return <div>{data}</div>;
}✅ Правильно:
// Разделение ответственности
async function ServerComponent() {
const data = await fetch('/api');
return <ClientComponent initialData={data} />;
}
'use client';
function ClientComponent({ initialData }) {
const [state, setState] = useState(0);
return <div>{initialData.title}</div>;
}React Server Components — это будущее React разработки:
Используйте RSC для создания быстрых и эффективных приложений! 🚀