فارسی

با Suspense، دریافت داده کارآمد در React را فعال کنید! استراتژی‌های مختلف، از بارگذاری در سطح کامپوننت تا دریافت موازی داده، را کاوش کرده و برنامه‌های واکنش‌گرا و کاربرپسند بسازید.

React Suspense: استراتژی‌های دریافت داده برای برنامه‌های مدرن

React Suspense یک ویژگی قدرتمند است که در React 16.6 معرفی شده و عملیات ناهمگام، به ویژه دریافت داده را ساده می‌کند. این ویژگی به شما اجازه می‌دهد تا رندر کامپوننت را در حین انتظار برای بارگذاری داده «معلق» کنید و روشی اعلانی‌تر و کاربرپسندتر برای مدیریت وضعیت‌های بارگذاری فراهم می‌کند. این راهنما به بررسی استراتژی‌های مختلف دریافت داده با استفاده از React Suspense می‌پردازد و بینش‌های عملی برای ساخت برنامه‌های واکنش‌گرا و با کارایی بالا ارائه می‌دهد.

درک React Suspense

قبل از پرداختن به استراتژی‌های خاص، بیایید مفاهیم اصلی React Suspense را درک کنیم:

استراتژی‌های دریافت داده با Suspense

در اینجا چندین استراتژی مؤثر برای دریافت داده با استفاده از React Suspense آورده شده است:

1. دریافت داده در سطح کامپوننت

این ساده‌ترین رویکرد است که در آن هر کامپوننت داده‌های خود را درون یک مرز Suspense دریافت می‌کند. این روش برای کامپوننت‌های ساده با نیازمندی‌های داده مستقل مناسب است.

مثال:

فرض کنید یک کامپوننت UserProfile داریم که نیاز به دریافت داده‌های کاربر از یک API دارد:

// یک ابزار ساده برای دریافت داده (با کتابخانه دلخواه خود جایگزین کنید)
const fetchData = (url) => {
  let status = 'pending';
  let result;
  let suspender = fetch(url)
    .then(res => {
      if (!res.ok) {
        throw new Error(`HTTP error! Status: ${res.status}`);
      }
      return res.json();
    })
    .then(
      res => {
        status = 'success';
        result = res;
      },
      err => {
        status = 'error';
        result = err;
      }
    );

  return {
    read() {
      if (status === 'pending') {
        throw suspender;
      } else if (status === 'error') {
        throw result;
      }
      return result;
    }
  };
};

const userResource = fetchData('/api/user/123');

function UserProfile() {
  const user = userResource.read();
  return (
    <div>
      <h2>{user.name}</h2>
      <p>ایمیل: {user.email}</p>
    </div>
  );
}

function App() {
  return (
    <Suspense fallback={<div>در حال بارگذاری اطلاعات کاربر...</div>}>
      <UserProfile />
    </Suspense>
  );
}

توضیح:

مزایا:

معایب:

2. دریافت موازی داده

برای جلوگیری از دریافت داده آبشاری، می‌توانید چندین درخواست داده را به صورت همزمان آغاز کنید و از Promise.all یا تکنیک‌های مشابه برای منتظر ماندن برای همه آن‌ها قبل از رندر کامپوننت‌ها استفاده کنید. این کار زمان کلی بارگذاری را به حداقل می‌رساند.

مثال:

const userResource = fetchData('/api/user/123');
const postsResource = fetchData('/api/user/123/posts');

function UserProfile() {
  const user = userResource.read();
  const posts = postsResource.read();

  return (
    <div>
      <h2>{user.name}</h2>
      <p>ایمیل: {user.email}</p>
      <h3>پست‌ها:</h3>
      <ul>
        {posts.map(post => (<li key={post.id}>{post.title}</li>))}
      </ul>
    </div>
  );
}

function App() {
  return (
    <Suspense fallback={<div>در حال بارگذاری اطلاعات کاربر و پست‌ها...</div>}>
      <UserProfile />
    </Suspense>
  );
}

توضیح:

مزایا:

معایب:

3. هیدراتاسیون انتخابی (برای رندر سمت سرور - SSR)

هنگام استفاده از رندر سمت سرور (SSR)، می‌توان از Suspense برای هیدراته کردن انتخابی بخش‌هایی از صفحه استفاده کرد. این بدان معناست که می‌توانید ابتدا هیدراته کردن مهم‌ترین بخش‌های صفحه را در اولویت قرار دهید و زمان رسیدن به تعامل (TTI) و عملکرد درک شده را بهبود بخشید. این روش در سناریوهایی مفید است که می‌خواهید طرح‌بندی اصلی یا محتوای اصلی را هرچه سریع‌تر نمایش دهید، در حالی که هیدراتاسیون کامپوننت‌های کمتر حیاتی را به تعویق می‌اندازید.

مثال (مفهومی):

// سمت سرور:
<Suspense fallback={<div>در حال بارگذاری محتوای حیاتی...</div>}>
  <CriticalContent />
</Suspense>
<Suspense fallback={<div>در حال بارگذاری محتوای اختیاری...</div>}>
  <OptionalContent />
</Suspense>

توضیح:

مزایا:

معایب:

4. کتابخانه‌های دریافت داده با پشتیبانی از Suspense

چندین کتابخانه محبوب دریافت داده دارای پشتیبانی داخلی از React Suspense هستند. این کتابخانه‌ها اغلب روشی راحت‌تر و کارآمدتر برای دریافت داده و یکپارچه‌سازی با Suspense ارائه می‌دهند. برخی از نمونه‌های قابل توجه عبارتند از:

مثال (با استفاده از SWR):

import useSWR from 'swr'

const fetcher = (...args) => fetch(...args).then(res => res.json())

function UserProfile() {
  const { data: user, error } = useSWR('/api/user/123', fetcher, { suspense: true })

  if (error) return <div>بارگذاری ناموفق بود</div>
  if (!user) return <div>در حال بارگذاری...</div> // این بخش به احتمال زیاد با Suspense هرگز رندر نمی‌شود

  return (
    <div>
      <h2>{user.name}</h2>
      <p>ایمیل: {user.email}</p>
    </div>
  )
}

function App() {
  return (
    <Suspense fallback={<div>در حال بارگذاری اطلاعات کاربر...</div>}>
      <UserProfile />
    </Suspense>
  );
}

توضیح:

مزایا:

معایب:

مدیریت خطا با Suspense

مدیریت خطا هنگام استفاده از Suspense بسیار مهم است. React یک کامپوننت ErrorBoundary برای گرفتن خطاهایی که در مرزهای Suspense رخ می‌دهند، فراهم می‌کند.

مثال:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // وضعیت را به‌روزرسانی کنید تا رندر بعدی رابط کاربری جایگزین را نشان دهد.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // همچنین می‌توانید خطا را در یک سرویس گزارش خطا ثبت کنید
    console.error(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // می‌توانید هر رابط کاربری جایگزین سفارشی را رندر کنید
      return <h1>مشکلی پیش آمده است.</h1>;
    }

    return this.props.children; 
  }
}

function App() {
  return (
    <ErrorBoundary>
      <Suspense fallback={<div>در حال بارگذاری...</div>}>
        <UserProfile />
      </Suspense>
    </ErrorBoundary>
  );
}

توضیح:

بهترین شیوه‌ها برای استفاده از React Suspense

مثال‌های دنیای واقعی

React Suspense را می‌توان در سناریوهای مختلفی به کار برد، از جمله:

مثال ۱: پلتفرم تجارت الکترونیک بین‌المللی

یک پلتفرم تجارت الکترونیک را تصور کنید که به مشتریان در کشورهای مختلف خدمات می‌دهد. جزئیات محصول، مانند قیمت‌ها و توضیحات، ممکن است نیاز به دریافت بر اساس موقعیت مکانی کاربر داشته باشد. می‌توان از Suspense برای نمایش یک نشانگر بارگذاری در حین دریافت اطلاعات محصول محلی‌شده استفاده کرد.

function ProductDetails({ productId, locale }) {
  const productResource = fetchData(`/api/products/${productId}?locale=${locale}`);
  const product = productResource.read();

  return (
    <div>
      <h2>{product.name}</h2>
      <p>قیمت: {product.price}</p>
      <p>توضیحات: {product.description}</p>
    </div>
  );
}

function App() {
  const userLocale = getUserLocale(); // تابعی برای تعیین موقعیت مکانی کاربر
  return (
    <Suspense fallback={<div>در حال بارگذاری جزئیات محصول...</div>}>
      <ProductDetails productId="123" locale={userLocale} />
    </Suspense>
  );
}

مثال ۲: فید رسانه اجتماعی جهانی

یک پلتفرم رسانه اجتماعی را در نظر بگیرید که فیدی از پست‌های کاربران در سراسر جهان را نمایش می‌دهد. هر پست ممکن است شامل متن، تصاویر و ویدیوهایی باشد که بارگذاری آنها زمان‌های متفاوتی می‌برد. می‌توان از Suspense برای نمایش جایگزین‌هایی برای هر پست در حین بارگذاری محتوای آنها استفاده کرد و تجربه پیمایش روان‌تری را فراهم نمود.

function Post({ postId }) {
  const postResource = fetchData(`/api/posts/${postId}`);
  const post = postResource.read();

  return (
    <div>
      <p>{post.text}</p>
      {post.image && <img src={post.image} alt="تصویر پست" />}
      {post.video && <video src={post.video} controls />}
    </div>
  );
}

function App() {
  const postIds = getPostIds(); // تابعی برای بازیابی لیست شناسه‌های پست‌ها
  return (
    <div>
      {postIds.map(postId => (
        <Suspense key={postId} fallback={<div>در حال بارگذاری پست...</div>}>
          <Post postId={postId} />
        </Suspense>
      ))}
    </div>
  );
}

نتیجه‌گیری

React Suspense ابزاری قدرتمند برای مدیریت دریافت داده ناهمگام در برنامه‌های React است. با درک استراتژی‌های مختلف دریافت داده و بهترین شیوه‌ها، می‌توانید برنامه‌های واکنش‌گرا، کاربرپسند و با عملکرد بالا بسازید که تجربه کاربری عالی ارائه می‌دهند. با استراتژی‌ها و کتابخانه‌های مختلف آزمایش کنید تا بهترین رویکرد را برای نیازهای خاص خود بیابید.

همچنان که React به تکامل خود ادامه می‌دهد، احتمالاً Suspense نقش مهم‌تری در دریافت داده و رندر ایفا خواهد کرد. آگاه ماندن از آخرین تحولات و بهترین شیوه‌ها به شما کمک می‌کند تا از پتانسیل کامل این ویژگی بهره‌مند شوید.