برنامه نویسی

مهارت های React خود را بالا ببرید: 10 تکنیک پیشرفته برای افراد ارشد

سابر

هرچه برنامه های React پیچیده تر می شوند ، الگوهای “بسیار خوب” هنگام شروع کار ممکن است شروع به احساس محدودیت کنند. شاید شما یک MVP موفق ایجاد کرده باشید ، اما اکنون در حال مشاهده مشکلات عملکرد ظریف هستید. یا شاید مدیریت دولت شما درهم و برهم شده باشد ، و منطق واکشی داده های شما به چیزی غیرقابل تشخیص قارچ شده است.

1. از useCallback با یک مرجع خدمات مداوم استفاده کنید
ما اغلب می بینیم که UseCallback برای یادآوری توابع Arrow Inline در دستگیرندگان رویداد استفاده می شود. ما این کار را انجام می دهیم تا اطمینان حاصل کنیم که مرجع عملکرد پایدار است و هنگام تصویب به عنوان یک پیشنهاد ، مجدداً غیرضروری را تحریک نمی کند.

اما با افزایش سطح ، می یابید که می توانید از آن برای حفظ منابع پایدار به خدمات پیچیده تر-مانند شبکه های وب ، کارگران یا سایر منابع مداوم استفاده کنید-بنابراین در هر رندر دوباره به طور غیر ضروری ایجاد نمی شوند.

این رویکرد بر اساس اصول اولیه Useref و UseCallback بنا شده است: شما اطمینان می دهید که یک سرویس خدمات طولانی مدت پایدار است. این می تواند عملکرد بالای عملکرد را ذخیره کرده و از اتصال مجدد ناخواسته جلوگیری کند.

مثال:

function createExpensiveService() {
  // Pretend this sets up a WebSocket or a shared worker
  return { send: (msg) => console.log('Sending:', msg) };
}

function usePersistentService() {
  const serviceRef = React.useRef(createExpensiveService());
  // Memoize the send function so it never changes
  const stableSend = React.useCallback((msg) => {
    serviceRef.current.send(msg);
  }, []);
  return stableSend;
}
function MyComponent() {
  const send = usePersistentService();
  return ;
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

2. استفاده از یک Ref برای سادگی به جای دولت
بعضی اوقات ما اشتباه می کنیم که همه داده های در حال تغییر را در یک حالت قرار دهیم. اما گاهی اوقات ، شما فقط به مقداری احتیاج دارید که باعث ایجاد مجدد شود. در این موارد ، استفاده از Ref در واقع ساده تر و کارآمدتر است.

به عنوان مثال ، پیشخوان را تصور کنید که فقط باید بدون تأثیرگذاری بر UI ، در داخل بخوانید و به روز کنید. یک Ref عالی است. نیازی به استفاده از ماستاژ یا رندرهای فانتزی نیست – فقط یک جعبه پایدار برای ذخیره یک مقدار تغییر.

مثال:

function MyCounter() {
  const counterRef = React.useRef(0);
  const increment = () => {
    counterRef.current++;
    console.log('Ref count is now:', counterRef.current);
  };
  return ;
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

3. استفاده از تعلیق برای واکشی داده ها با حافظه نهان منابع
در بسیاری از برنامه های REACT ، داده های واکشی شامل استفاده ، حالت های بارگیری و یک دسته از چک های دستی است. تعلیق می تواند با اجازه دادن به مؤلفه ها از یک منبع داده ویژه ، همه اینها را ساده کند. اگر داده ها آماده نباشند ، این مؤلفه به طور خودکار به حالت تعلیق در می آید و تا زمان رسیدن داده ها یک رابط کاربری برگشتی نشان می دهد. این رویکرد منطق بارگیری را متمرکز می کند و اجزای شما را تمیز تر و بیشتر روی ارائه می دهد.

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

function createResource(fetchFn) {
  let status="pending";
  let result;
  const promise = fetchFn().then(
    data => { status="success"; result = data; },
    err => { status="error"; result = err; }
  );
  return {
    read() {
      if (status === 'pending') throw promise;
      if (status === 'error') throw result;
      return result;
    }
  };
}

const userResource = createResource(() => fetch('/api/user').then(r => r.json()));

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

Hello, {user.name}!

; } function App() { return ( Loading user data...

}>

) ؛ }

حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

4. تعلیق با واردات پویا و نکات از پیش بارگذاری
تقسیم کد با React.Lazy () متداول است ، اما می توانید قبل از اینکه کاربر به آن احتیاج داشته باشد ، با استفاده از پیش بارگذاری بیشتر آن را انجام دهید. این باعث می شود زمان انتظار زمانی که در نهایت روی یک دکمه کلیک می کنند یا به یک مسیر خاص حرکت می کنند ، کاهش می یابد. بارگیری اجزای سنگین خود را در پس زمینه شروع کنید تا در صورت لزوم فوراً آماده شوند.

مثال:

const HeavyChart = React.lazy(() => import('./HeavyChart'));

function usePreloadHeavyChart() {
  React.useEffect(() => {
    import('./HeavyChart'); // start preloading on mount
  }, []);
}

function Dashboard() {
  usePreloadHeavyChart();
  return (
    Loading Chart...

}>

) ؛ }

حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

5. مرزهای خطا که به طور خودکار دوباره امتحان می کنند
در بعضی از مواقع ، ممکن است چیزی در برنامه شما شکست بخورد-شاید یک درخواست شبکه یا یک مؤلفه تنبل باشد. مرزهای خطای سنتی یک رابط کاربری Fallback را نشان می دهد و در آنجا متوقف می شود. با تقویت آنها ، می توانید به صورت خودکار بهبود یابید ، پس از یک تأخیر کوتاه ، دوباره امتحان کنید. این می تواند یک پیشرفت عالی در تجربه کاربر باشد و یک جلوه موقتی را به یک بازیابی بدون درز تبدیل کند.

مثال:

class AutoRetryErrorBoundary extends React.Component {
  state = { hasError: false, attempt: 0 };
  static getDerivedStateFromError() {
    return { hasError: true };
  }
  componentDidUpdate() {
    if (this.state.hasError) {
      setTimeout(() => {
        this.setState(s => ({ hasError: false, attempt: s.attempt + 1 }));
      }, 2000);
    }
  }
  render() {
    if (this.state.hasError) return 

Retrying...

; return this.props.children(this.state.attempt); } } function UnstableComponent({ attempt }) { if (attempt < 2) throw new Error('Simulated Crash!'); return

Loaded on attempt {attempt}

; } // Usage {(attempt) => }
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

6. لیست های مجازی سازی با ارتفاع مورد پویاحرف
هنگامی که لیست های عظیمی دارید ، ارائه هر مورد می تواند عملکرد را از بین ببرد. کتابخانه های مجازی سازی (مانند React-Window) فقط آنچه را که قابل مشاهده است ، ارائه می دهند. اما اگر موارد دارای ارتفاعات غیرقابل پیش بینی باشند ، چه می شود؟ شما می توانید آنها را به صورت پویا اندازه گیری کرده و آن اندازه گیری ها را به منطق مجازی سازی خود برگردانید. این باعث می شود هم استفاده از حافظه و هم زمان ارائه ، و نگه داشتن پیچ و خم ابریشمی را صاف نگه دارید.

مثال:

import { VariableSizeList as List } from 'react-window';

function useDynamicMeasurement(items) {
  const sizeMap = React.useRef({});
  const refCallback = index => el => {
    if (el) {
      const height = el.getBoundingClientRect().height;
      sizeMap.current[index] = height;
    }
  };
  const getSize = index => sizeMap.current[index] || 50;
  return { refCallback, getSize };
}

function DynamicHeightList({ items }) {
  const { refCallback, getSize } = useDynamicMeasurement(items);
  return (
    
      {({ index, style }) => (
        

{items[index]}

)}
); }
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

7. با استفاده از یک دستگاه حالت برای جریان های پیچیده UI
هنگامی که مؤلفه شما شروع به احساس اسپاگتی در صورت اظهارات می کند ، یک دستگاه دولتی می تواند کمک کند. ابزارهایی مانند XState به خوبی با قلاب React ادغام می شوند. به جای اینکه چندین بولی را جمع کنید ، حالت ها و انتقال را در یک نمودار واحد و تمیز تعریف می کنید. این یک تغییر مدل ذهنی است: شما در حال نوشتن یک “نقشه” از چگونگی جریان UI خود هستید و درک و اشکال زدایی را آسان تر می کنید.

مثال:

import { useMachine } from '@xstate/react';
import { createMachine } from 'xstate';

const formMachine = createMachine({
  initial: 'editing',
  states: {
    editing: { on: { SUBMIT: 'validating' } },
    validating: {
      invoke: {
        src: 'validateForm',
        onDone: 'success',
        onError: 'error'
      }
    },
    success: {},
    error: {}
  }
});

function Form() {
  const [state, send] = useMachine(formMachine, {
    services: { validateForm: async () => {/* validation logic */} }
  });
  return (
    
  );
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

8. همزمانی کنترل شده با usetransition و صف کار
React 18 Usetransition را برای کمک به شما در به روزرسانی های خاص دولت به عنوان “غیر فوری” معرفی کرد. این می تواند یک تغییر دهنده بازی برای عملکرد تحت بار سنگین باشد. تصور کنید که مقادیر زیادی از داده ها را بدست آورید یا محاسبات گران قیمت را انجام دهید. با تعویق به روزرسانی های غیر فوری ، UI را پاسخگو نگه می دارید و از قفل کردن موضوع اصلی خودداری می کنید.

مثال:

function ComplexUI() {
  const [isPending, startTransition] = React.useTransition();
  const [data, setData] = React.useState([]);

  function loadMore() {
    startTransition(() => {
      setData(old => [...old, ...generateMoreData()]);
    });
  }
  return (
    <>
      
      {isPending && Loading more data...}
      
    >
  );
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

9. UseimperativeHandle برای ایجاد API های مؤلفه کنترل شده
بعضی اوقات برای کنترل مستقیم کودک به یک جزء والدین نیاز دارید – مانند تماس با ChildRef.Current.Focus () در ورودی سفارشی. UseimperativeHandle قلاب است که به شما امکان می دهد آنچه را که والدین هنگام استفاده از Ref در یک مؤلفه کودک می بیند ، تعریف کنید. این مناسب برای ایجاد API های مؤلفه مرتب و کنترل شده است که احساس می کنند یک روش را در یک نمونه کلاس فراخوانی می کنند ، اما به روشی دوستانه واکنش نشان می دهند.

مثال:

10. هیدراتاسیون مترقی با قلاب سفارشی
رندر سمت سرور (SSR) می تواند محتوای شما را سریع به کاربر برساند ، اما آبرسانی یک برنامه بزرگ به یکباره می تواند تعامل را کند کند. با تأخیر در هیدراتاسیون برای قسمتهای غیر مهم صفحه خود ، می توانید بار اولیه را خوشحال کنید. یک قلاب سفارشی که به تدریج اجزای خاصی را پس از تأخیر هیدراته می کند ، می تواند SSR را حتی یکپارچه تر کند.

مثال:

function useProgressiveHydration(delay = 1000) {
  const [hydrated, setHydrated] = React.useState(false);
  React.useEffect(() => {
    const t = setTimeout(() => setHydrated(true), delay);
    return () => clearTimeout
  }, [delay]);
  return hydrated;
}

function HeavyComponent() {
  const hydrated = useProgressiveHydration();
  return hydrated ?  : ;
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

افکار نهایی
این تکنیک ها به معنای استفاده همه به یکباره نیست و مطمئناً در هر پایگاه کد نیست. آنها ابزاری هستند – پیشرفته – که با رشد برنامه ها و مهارت های شما مفید می شوند. وقتی شروع به اجرای محدودیت های الگوهای ساده تر می کنید ، این رویکردها را در نظر بگیرید.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا