قدرت React Suspense را برای بهبود واکشی داده، تقسیم کد و تجربه کاربری روانتر آزاد کنید. نحوه پیاده سازی Suspense را با مثال های عملی و بهترین شیوه ها بیاموزید.
React Suspense: راهنمای جامع برای واکشی داده و تقسیم کد
React Suspense یک ویژگی قدرتمند است که در React 16.6 معرفی شده است و به شما امکان می دهد رندر کامپوننت را در حین انتظار برای چیزی، مانند بارگیری داده ها یا دانلود کد، "به حالت تعلیق درآورید". این یک روش اعلانی برای مدیریت حالات بارگیری ارائه می دهد و با رسیدگی مناسب به عملیات ناهمزمان، تجربه کاربری را بهبود می بخشد. این راهنما شما را با مفاهیم Suspense، موارد استفاده و نمونه های عملی نحوه پیاده سازی آن در برنامه های React خود آشنا می کند.
React Suspense چیست؟
Suspense یک کامپوننت React است که کامپوننت های دیگر را در بر می گیرد و به شما امکان می دهد در حالی که آن کامپوننت ها منتظر حل شدن یک promise هستند، یک رابط کاربری fallback (به عنوان مثال، یک اسپینر بارگیری) نمایش دهید. این promise می تواند مربوط به موارد زیر باشد:
- واکشی داده: منتظر ماندن برای بازیابی داده ها از یک API.
- تقسیم کد: منتظر ماندن برای دانلود و تجزیه ماژول های JavaScript.
قبل از Suspense، مدیریت حالات بارگیری اغلب شامل رندرینگ شرطی پیچیده و رسیدگی دستی به عملیات ناهمزمان بود. Suspense با ارائه یک رویکرد اعلانی، این کار را ساده می کند و کد شما را تمیزتر و قابل نگهداری تر می کند.
مفاهیم کلیدی
- کامپوننت Suspense: خود کامپوننت
<Suspense>. این کامپوننت یک prop با نامfallbackمی پذیرد که رابط کاربری را که باید در حین به حالت تعلیق درآمدن کامپوننت های پیچیده شده نمایش داده شود، مشخص می کند. - React.lazy(): تابعی که با وارد کردن پویا کامپوننت ها، تقسیم کد را فعال می کند. این تابع یک
Promiseرا برمی گرداند که پس از بارگیری کامپوننت، resolve می شود. - ادغام Promise: Suspense به طور یکپارچه با Promises ادغام می شود. هنگامی که یک کامپوننت تلاش می کند تا داده ها را از یک Promise که هنوز resolve نشده است، رندر کند، "به حالت تعلیق در می آید" و رابط کاربری fallback را نمایش می دهد.
موارد استفاده
1. واکشی داده با Suspense
یکی از موارد استفاده اصلی Suspense، مدیریت واکشی داده است. به جای مدیریت دستی حالات بارگیری با رندرینگ شرطی، می توانید از Suspense برای نمایش اعلانی یک نشانگر بارگیری در حین انتظار برای رسیدن داده ها استفاده کنید.
مثال: واکشی داده های کاربر از یک API
فرض کنید یک کامپوننت دارید که داده های کاربر واکشی شده از یک API را نمایش می دهد. بدون Suspense، ممکن است کدی مانند این داشته باشید:
import React, { useState, useEffect } from 'react';
function UserProfile() {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchData() {
try {
const response = await fetch('https://api.example.com/users/123');
const data = await response.json();
setUser(data);
} catch (err) {
setError(err);
} finally {
setIsLoading(false);
}
}
fetchData();
}, []);
if (isLoading) {
return <p>Loading user data...</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
if (!user) {
return <p>No user data available.</p>;
}
return (
<div>
<h2>{user.name}</h2>
<p>Email: {user.email}</p>
</div>
);
}
export default UserProfile;
این کد کار می کند، اما شامل مدیریت چندین متغیر state (isLoading، error، user) و منطق رندرینگ شرطی است. با Suspense، می توانید این را با استفاده از یک کتابخانه واکشی داده مانند SWR یا TanStack Query (که قبلاً React Query بود) که برای کار یکپارچه با Suspense طراحی شده اند، ساده کنید.
در اینجا نحوه استفاده از SWR با Suspense آورده شده است:
import React from 'react';
import useSWR from 'swr';
// A simple fetcher function
const fetcher = (...args) => fetch(...args).then(res => res.json());
function UserProfile() {
const { data: user, error } = useSWR('/api/users/123', fetcher, { suspense: true });
if (error) {
return <p>Error: {error.message}</p>;
}
return (
<div>
<h2>{user.name}</h2>
<p>Email: {user.email}</p>
</div>
);
}
function App() {
return (
<Suspense fallback={<p>Loading user data...</p>}>
<UserProfile />
</Suspense>
);
}
export default App;
در این مثال:
- ما از
useSWRبرای واکشی داده های کاربر استفاده می کنیم. گزینهsuspense: trueبه SWR می گوید که اگر داده ها هنوز در دسترس نیستند، یک Promise پرتاب کند. - کامپوننت
UserProfileنیازی به مدیریت صریح حالات بارگیری یا خطا ندارد. به سادگی داده های کاربر را در صورت در دسترس بودن رندر می کند. - کامپوننت
<Suspense>Promise پرتاب شده توسط SWR را می گیرد و رابط کاربری fallback (<p>Loading user data...</p>) را در حین واکشی داده ها نمایش می دهد.
این رویکرد منطق کامپوننت شما را ساده می کند و استدلال در مورد واکشی داده ها را آسان تر می کند.
ملاحظات جهانی برای واکشی داده:
هنگام ساخت برنامه هایی برای مخاطبان جهانی، به موارد زیر توجه کنید:
- تاخیر شبکه: کاربران در مناطق جغرافیایی مختلف ممکن است تاخیر شبکه متفاوتی را تجربه کنند. Suspense می تواند با نمایش نشانگرهای بارگیری در حین واکشی داده ها از سرورهای دور، به ارائه یک تجربه کاربری بهتر کمک کند. استفاده از شبکه تحویل محتوا (CDN) را برای ذخیره داده های خود در نزدیکی کاربران خود در نظر بگیرید.
- بومی سازی داده: اطمینان حاصل کنید که API شما از بومی سازی داده پشتیبانی می کند و به شما امکان می دهد داده ها را به زبان و قالب دلخواه کاربر ارائه دهید.
- در دسترس بودن API: در دسترس بودن و عملکرد API های خود را از مناطق مختلف نظارت کنید تا از تجربه کاربری ثابت اطمینان حاصل کنید.
2. تقسیم کد با React.lazy() و Suspense
تقسیم کد تکنیکی برای شکستن برنامه شما به قطعات کوچکتر است که می توانند در صورت تقاضا بارگیری شوند. این می تواند به طور قابل توجهی زمان بارگیری اولیه برنامه شما را بهبود بخشد، به خصوص برای پروژه های بزرگ و پیچیده.
React تابع React.lazy() را برای تقسیم کد کامپوننت ها ارائه می دهد. هنگام استفاده با Suspense، به شما امکان می دهد در حین انتظار برای دانلود و تجزیه کامپوننت، یک رابط کاربری fallback نمایش دهید.
مثال: بارگیری تنبل یک کامپوننت
import React, { Suspense, lazy } from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<p>Loading...</p>}>
<OtherComponent />
</Suspense>
</div>
);
}
export default MyComponent;
در این مثال:
- ما از
React.lazy()برای وارد کردن پویاOtherComponentاستفاده می کنیم. این یک Promise را برمی گرداند که پس از بارگیری کامپوننت، resolve می شود. - ما
<OtherComponent />را با<Suspense>می پیچیم و یک prop با نامfallbackارائه می دهیم. - در حالی که
OtherComponentدر حال بارگیری است، رابط کاربری fallback (<p>Loading...</p>) نمایش داده می شود. پس از بارگیری کامپوننت، رابط کاربری fallback را جایگزین می کند.
مزایای تقسیم کد:
- بهبود زمان بارگیری اولیه: با بارگیری تنها کد لازم برای نمای اولیه، می توانید زمانی را که طول می کشد تا برنامه شما تعاملی شود، کاهش دهید.
- کاهش اندازه بسته نرم افزاری: تقسیم کد می تواند به کاهش اندازه کلی بسته نرم افزاری JavaScript برنامه شما کمک کند، که می تواند عملکرد را بهبود بخشد، به خصوص در اتصالات با پهنای باند کم.
- تجربه کاربری بهتر: با ارائه بارگیری اولیه سریعتر و فقط بارگیری کد در صورت نیاز، می توانید یک تجربه کاربری روان تر و پاسخگوتر ایجاد کنید.
تکنیک های پیشرفته تقسیم کد:
- تقسیم کد مبتنی بر مسیر: برنامه خود را بر اساس مسیرها تقسیم کنید، به طوری که هر مسیر فقط کدی را که نیاز دارد بارگیری کند. این را می توان به راحتی با کتابخانه هایی مانند React Router به دست آورد.
- تقسیم کد مبتنی بر کامپوننت: کامپوننت های جداگانه را به قطعات جداگانه تقسیم کنید، به خصوص برای کامپوننت های بزرگ یا کم استفاده.
- واردات پویا: از واردات پویا در کامپوننت های خود برای بارگیری کد در صورت تقاضا بر اساس تعاملات کاربر یا سایر شرایط استفاده کنید.
3. حالت همزمان و Suspense
Suspense یک عنصر کلیدی برای حالت همزمان React است، مجموعه ای از ویژگی های جدید که React را قادر می سازد تا به طور همزمان روی چندین کار کار کند. حالت همزمان به React اجازه می دهد تا به روز رسانی های مهم را در اولویت قرار دهد، وظایف طولانی مدت را قطع کند و پاسخگویی برنامه شما را بهبود بخشد.
با حالت همزمان و Suspense، React می تواند:
- قبل از اینکه تمام داده ها در دسترس باشند، شروع به رندر کردن کامپوننت ها کنید: React می تواند رندر یک کامپوننت را حتی اگر برخی از وابستگی های داده آن هنوز در حال واکشی هستند، شروع کند. این به React اجازه می دهد تا زودتر یک رابط کاربری جزئی را نشان دهد و عملکرد درک شده برنامه شما را بهبود بخشد.
- قطع و از سرگیری رندر: اگر در حالی که React در حال رندر کردن یک کامپوننت است، یک به روز رسانی با اولویت بالاتر وارد شود، می تواند فرآیند رندر را قطع کند، به روز رسانی با اولویت بالاتر را انجام دهد و سپس رندر کامپوننت را بعداً از سر بگیرد.
- جلوگیری از مسدود کردن رشته اصلی: حالت همزمان به React اجازه می دهد تا وظایف طولانی مدت را بدون مسدود کردن رشته اصلی انجام دهد، که می تواند از غیرپاسخگو شدن رابط کاربری جلوگیری کند.
برای فعال کردن حالت همزمان، می توانید از API createRoot در React 18 استفاده کنید:
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
const container = document.getElementById('root');
const root = createRoot(container); // Create a root.
root.render(<App />);
بهترین شیوه ها برای استفاده از Suspense
- از یک کتابخانه واکشی داده استفاده کنید: استفاده از یک کتابخانه واکشی داده مانند SWR یا TanStack Query را در نظر بگیرید که برای کار یکپارچه با Suspense طراحی شده اند. این کتابخانه ها ویژگی هایی مانند ذخیره سازی، تلاش مجدد خودکار و مدیریت خطا را ارائه می دهند که می تواند منطق واکشی داده شما را ساده کند.
- رابط کاربری Fallback معناداری ارائه دهید: رابط کاربری fallback باید نشانه واضحی از بارگیری چیزی ارائه دهد. از اسپینرها، نوارهای پیشرفت یا لودرهای اسکلتی برای ایجاد یک تجربه بارگیری بصری جذاب و آموزنده استفاده کنید.
- خطاها را به خوبی مدیریت کنید: از مرزهای خطا برای گرفتن خطاهایی که در طول رندر رخ می دهند استفاده کنید. این می تواند از خراب شدن کل برنامه شما جلوگیری کند و تجربه کاربری بهتری را ارائه دهد.
- تقسیم کد را بهینه کنید: از تقسیم کد به صورت استراتژیک برای کاهش زمان بارگیری اولیه برنامه خود استفاده کنید. کامپوننت های بزرگ یا کم استفاده را شناسایی کرده و آنها را به قطعات جداگانه تقسیم کنید.
- پیاده سازی Suspense خود را تست کنید: پیاده سازی Suspense خود را به طور کامل تست کنید تا مطمئن شوید که به درستی کار می کند و برنامه شما حالات بارگیری و خطاها را به خوبی مدیریت می کند.
مدیریت خطا با مرزهای خطا
در حالی که Suspense حالت *بارگیری* را مدیریت می کند، مرزهای خطا حالت *خطا* را در طول رندر مدیریت می کنند. مرزهای خطا کامپوننت های React هستند که خطاهای JavaScript را در هر نقطه از درخت کامپوننت فرزند خود می گیرند، آن خطاها را ثبت می کنند و به جای خراب کردن کل درخت کامپوننت، یک رابط کاربری fallback نمایش می دهند.
در اینجا یک مثال اساسی از یک مرز خطا آورده شده است:
import React, { Component } from 'react';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
console.error(error, errorInfo);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary;
برای استفاده از مرز خطا، آن را در اطراف کامپوننتی که ممکن است خطا پرتاب کند، بپیچید:
import ErrorBoundary from './ErrorBoundary';
import MyComponent from './MyComponent';
function App() {
return (
<ErrorBoundary>
<MyComponent />
</ErrorBoundary>
);
}
export default App;
با ترکیب Suspense و مرزهای خطا، می توانید یک برنامه قوی و انعطاف پذیر ایجاد کنید که هر دو حالت بارگیری و خطاها را به خوبی مدیریت می کند.
مثال های دنیای واقعی
در اینجا چند مثال دنیای واقعی از نحوه استفاده از Suspense برای بهبود تجربه کاربری آورده شده است:
- وب سایت تجارت الکترونیک: از Suspense برای نمایش نشانگرهای بارگیری در حین واکشی جزئیات یا تصاویر محصول استفاده کنید. این می تواند از دیدن یک صفحه خالی در حین انتظار برای بارگیری داده ها جلوگیری کند.
- پلتفرم رسانه های اجتماعی: از Suspense برای بارگیری تنبل نظرات یا پست ها هنگام پیمایش کاربر به پایین صفحه استفاده کنید. این می تواند زمان بارگیری اولیه صفحه را بهبود بخشد و میزان داده ای را که باید دانلود شود کاهش دهد.
- برنامه داشبورد: از Suspense برای نمایش نشانگرهای بارگیری در حین واکشی داده ها برای نمودارها یا نمودارها استفاده کنید. این می تواند یک تجربه کاربری روان تر و پاسخگوتر ارائه دهد.
مثال: پلتفرم بین المللی تجارت الکترونیک
یک پلتفرم بین المللی تجارت الکترونیک را در نظر بگیرید که محصولات را در سطح جهانی می فروشد. این پلتفرم می تواند از Suspense و React.lazy() برای موارد زیر استفاده کند:
- بارگیری تنبل تصاویر محصول: از
React.lazy()برای بارگیری تصاویر محصول فقط زمانی که در نمای دیدنی قابل مشاهده هستند استفاده کنید. این می تواند به طور قابل توجهی زمان بارگیری اولیه صفحه لیست محصول را کاهش دهد. هر تصویر بارگیری شده تنبل را با<Suspense fallback={<img src="placeholder.png" alt="Loading..." />}>بپیچید تا یک تصویر placeholder در حین بارگیری تصویر واقعی نمایش داده شود. - تقسیم کد کامپوننت های خاص کشور: اگر پلتفرم دارای کامپوننت های خاص کشور است (به عنوان مثال، قالب بندی ارز، فیلدهای ورودی آدرس)، از
React.lazy()برای بارگیری این کامپوننت ها فقط زمانی که کاربر یک کشور خاص را انتخاب می کند استفاده کنید. - واکشی توضیحات محصول بومی شده: از یک کتابخانه واکشی داده مانند SWR با Suspense برای واکشی توضیحات محصول به زبان دلخواه کاربر استفاده کنید. یک نشانگر بارگیری را در حین واکشی توضیحات بومی شده نمایش دهید.
نتیجه گیری
React Suspense یک ویژگی قدرتمند است که می تواند به طور قابل توجهی تجربه کاربری برنامه های React شما را بهبود بخشد. Suspense با ارائه یک روش اعلانی برای مدیریت حالات بارگیری و تقسیم کد، کد شما را ساده می کند و استدلال در مورد عملیات ناهمزمان را آسان تر می کند. چه در حال ساخت یک پروژه شخصی کوچک باشید و چه یک برنامه سازمانی بزرگ، Suspense می تواند به شما کمک کند یک تجربه کاربری روان تر، پاسخگوتر و با عملکرد بهتر ایجاد کنید.
با ادغام Suspense با کتابخانه های واکشی داده و تکنیک های تقسیم کد، می توانید پتانسیل کامل حالت همزمان React را آزاد کنید و برنامه های وب مدرن و جذابی ایجاد کنید. Suspense را در آغوش بگیرید و توسعه React خود را به سطح بعدی ارتقا دهید.