۱۰ نکته کاربردی از React

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

ما در دوره فشرده آموزش React مفاهیم مهم‌تر و کاربردی React را بررسی کرده‌ایم.

۱) React چیست؟ چرا باید از آن استفاده کنیم؟

React یک فریمورک نیست، بلکه یک کتابخانه جاوااسکریپت است.

ما از React استفاده می‌کنیم زیرا تمام قدرت جاوااسکریپت را به ما می‌دهد، اما ویژگی‌های built-in است که نحوه تفکر ما در مورد ساخت برنامه‌ها را بهبود می‌بخشد.

  • React این امکان را به ما می‌دهد تا به راحتی رابط کاربری(UI) را با ابزارهایی مانند JSX ایجاد کنیم.
  • یک کاربرد دیگر React این است که کامپوننت‌هایی در اختیار ما قرار می‌دهد که می‌توانیم به راحتی بخش‌هایی از رابط کاربری خود را به اشتراک بگذاریم، کاری که خود HTML ایستا نمی‌تواند انجام دهد.
  • React اجازه می‌دهد تا ما با استفاده از هوک‌ها رفتار با قابلیت استفاده مجدد را در هر یک از کامپوننت‌های خود ایجاد کنیم.
  • React در صورت تغییر داده‌ها بدون نیاز به به‌روزرسانی دستی DOM، به‌روزرسانی رابط کاربری ما را به عهده می‌گیرد.

توضیح تکمیلی: فریمورک‌هایی در React وجود دارد که هر آنچه را که برای ساختن یک برنامه نیاز داریم در اختیار ما قرار می‌دهد، مانند Next.js و Gatsby.

React به طور خاص برای ساخت برنامه‌های تک صفحه‌ای(single-page apps) ایجاد شده است. اما می‌توانیم موارد دیگر از جمله وبسایت‌ها، برنامه‌های تلفن همراه و غیره را نیز با همان مفاهیم React طراحی کنیم.

۲) JSX چیست؟

JSX راهی برای ایجاد رابط‌های کاربری React است که از سینتکس ساده HTML استفاده می‌کند. همچنین عملکرد و ماهیت پویا جاوااسکریپت را نیز به React اضافه می‌کند.

به طور خلاصه، منظور از JSX برای ساختار برنامه‌های React ما عبارت است از HTML + جاوااسکریپت.

اگرچه JSX شبیه HTML است، اما در پشت پرده در واقع فراخوانی تابع جاوااسکریپت صورت می‌گیرد. به این شکل که اگر یک div در JSX بنویسیم، در واقع معادل فراخوانی تابع ()React.createElement است.

ما می‌توانیم رابط کاربری خود را با فراخوانی دستی تابع React.createElement بسازیم. اما هر چه تعداد المنت‌های بیشتری اضافه کنیم، خواندن ساختاری که ایجاد کرده‌ایم سخت‌تر و سخت‌تر می‌شود.

مرورگر نمی‌تواند مفهوم خود JSX را درک کند. بنابراین اغلب از یک کامپایلر جاوااسکریپت به نام Babel استفاده می‌کنیم تا آنچه را که شبیه HTML است را به فراخوانی تابع جاوااسکریپت تبدیل کنیم تا مرورگر بتواند آن را درک کند.

۳) چگونه داده‌ها را به کامپوننت‌های React منتقل کنیم؟

دو راه اصلی برای انتقال داده به کامپوننت‌های React وجود دارد:

  1. props
  2. Context API

propsها داده‌هایی هستند که از parent مستقیم یک کامپوننت ارسال می‌شوند. آن‌ها در مولفه child تعریف می‌شوند و می‌توانند هر نامی داشته باشند و هر مقدار معتبری را بپذیرند.

function Blog() {
  const post = { title: "My Blog Post!" };

  return <BlogPost post={post} />;
}

propsها در کامپوننت child مورد استفاده قرار می‌گیرند و همیشه به عنوان ویژگی‌های یک object در دسترس هستند.

function BlogPost(props) {
  return <h1>{props.post.title}</h1>
}

از آنجایی که propsها ویژگی‌های یک object هستند، برای اینکه دسترسی سریع‌تری به آن‌ها داشته باشیم می‌توانیم عمل destructuring روی آن‌ها انجام دهیم.

function BlogPost({ post }) {
  return <h1>{post.title}</h1>
}

context داده‌ای است که از یک ارائه‌دهنده context به هر کامپوننتی که از آن استفاده می‌کند، منتقل می‌شود. context به ما این امکان را می‌دهد تا بدون استفاده از propsها در هر نقطه‌ای از برنامه خود به داده‌ها دسترسی داشته باشیم.

داده‌های context با استفاده از مؤلفه Context.Provider به مقدار props منتقل می‌شوند. پس می‌توانیم با استفاده از مولفه Context.Consumer یا هوک useContext از آن‌ها استفاده کنیم.

import { createContext, useContext } from 'react';

const PostContext = createContext()

function App() {
  const post = { title: "My Blog Post!" };

  return (
    <PostContext.Provider value={post}>
      <Blog />
    </PostContext.Provider>
  );
}

function Blog() {
  return <BlogPost />
}

function BlogPost() {
  const post = useContext(PostContext)

  return <h1>{post.title}</h1>
}

۴) تفاوت بین state و props چیست؟

stateها مقادیری هستند که می‌توانیم در کامپوننت‌های React بخوانیم و آن‌ها را به‌روزرسانی کنیم.

propsها مقادیری هستند که به کامپوننت‌های React ارسال می‌شوند و فقط خوانده می‌شوند (یعنی نباید به‌روزرسانی شوند).

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

state و props از این جهت شبیه هم هستند که هر تغییری در آن‌ها صورت بگیرد باعث می‌شود تا کامپوننت‌هایی که در آن‌ها وجود دارند re-render شوند.

۵) React Fragmentها برای چه مواردی استفاده می‌شود؟

React fragments یک ویژگی خاص در React است که به ما این امکان را می‌دهد تا بدون این که در DOM یک گره واقعی بسازیم بتوانیم گروه child از المنت‌ها یا کامپوننت‌ها را ایجاد کنیم.

سینتکس fragment شبیه مجموعه‌ای خالی از تگ <></> یا تگ‌هایی با برچسب React.Fragment است.

به عبارت ساده‌تر، گاهی اوقات لازم است چندین المنت React را تحت عنوان یک parent قرار دهیم، اما نمی‌خواهیم از یک المنت کلی HTML مانند div استفاده کنیم.

برای مثال، اگر بخواهیم برای یک table کدنویسی کنیم، این کد HTML نامعتبر خواهد بود:

function Table() {
  return (
    <table>
      <tr>
        <Columns />
      </tr>
    </table>
  );
}

function Columns() {
  return (
    <div>
      <td>Column 1</td>
      <td>Column 2</td>
    </div>
  );
}

ما می‌توانیم با استفاده از یک fragment به جای المنت div در کامپوننت Columns از این مشکل جلوگیری کنیم.

function Columns() {
  return (
    <>
      <td>Column 1</td>
      <td>Column 2</td>
    </>
  );
}

دلیل دیگر انتخاب fragment این است که گاهی اوقات افزودن یک المنت HTML اضافی ممکن است نحوه اعمال استایل‌های CSS ما را تغییر دهد.

۶) چرا در لیست‌های React به کلید نیاز داریم؟

کلیدها مقادیر منحصر به فرد هستند. وقتی از تابع ()map. برای ایجاد حلقه(loop) روی یک المنت یا کامپوننت استفاده می‌کنیم، باید آن را به کلید prop ارسال کنیم.

اگر روی یک المنت عمل mapping انجام دهیم، به شکل زیر خواهد بود:

posts.map(post => <li key={post.id}>{post.title}</li>)

یا اگر روی یک کامپوننت mapping انجام شود به این صورت است:

posts.map(post => <li key={post.id}>{post.title}</li>)

و در هر دو مورد، باید کلیدی اضافه کنیم که یک مقدار منحصر به فرد داشته باشد، در غیر این صورت با هشدار React مواجه خواهیم شد.

کاربرد این کلیدها در React این است که هر المنت یا کامپوننت را در لیست مشخص می‌کنند. در غیر این صورت اگر بخواهیم با درج موارد بیشتر و یا ویرایش موارد در این لیست، آن‌ها را تغییر دهیم React ترتیب قرار دادن آن‌ها را نمی‌داند. چون که React تمام کارهای مربوط به به‌روزرسانی DOM را(با استفاده از یکvirtual DOM) بر عهده می‌گیرد اما کلیدهایی برای React لازم است تا آن را به درستی به‌روزرسانی کند.

۷) Ref چیست؟ چگونه از آن استفاده کنیم؟

Ref ارجاع به یک المنت DOM در React است.

Refها با استفاده از هوک useRef ایجاد می‌شوند و می‌توانند بلافاصله در یک متغیر قرار بگیرند. سپس این متغیر به یک المنت React معین (نه یک کامپوننت) ارسال می‌شود تا به المنت DOM زیرمجموعه(یعنی div، span و غیره) ارجاع داده شود. خود المنت و خصوصیات آن اکنون در ویژگی current. مربوط به ref موجود هستند.

import { useRef } from 'react'

function MyComponent() {
  const ref = useRef();

  useEffect(() => {
    console.log(ref.current) // reference to div element
  }, [])

  return <div ref={ref} />
}

Refها اغلب به عنوان “escape hatch” شناخته می‌شوند تا بتوانند مستقیماً با یک المنت DOM کار کنند. کاربردی که دارند این است که به ما این اجازه را می‌دهند تا عملیات خاصی که از طریق React قابل انجام نیست، مانند پاک کردن داده‌ها یا focus کردن روی input را انجام دهیم.

۸) هوک useEffect چه کاربردی دارد؟

کاربرد هوک useEffect این است که برای انجام side effectها در کامپوننت‌های React مورد استفاده قرار می‌گیرد.

side effectها عملیاتی هستند که با “جهان بیرون” یا چیزی که خارج از context برنامه React ما وجود دارد، انجام می‌شوند.

برای اینکه چند نمونه‌ از side effectها را معرفی کنیم می‌توانیم به ارسال درخواست GET یا POST به endpoint یک API خارجی یا کار کردن با API یک مرورگر مانند window.navigator یا document.getElementById() اشاره کنیم.

ما نمی‌توانیم چنین عملیاتی را مستقیماً در بدنه کامپوننت React انجام دهیم. useEffect تابعی را به ما می‌دهد که می‌توانیم در آن side effectها را انجام دهیم و شامل یک آرایه از dependencyها است که تمامی مقادیر خارجی که تابع به آن‌ها وابستگی دارد را دربرمی‌گیرد.

اگر مقداری در آرایه dependencyها تغییر کند، تابع effect دوباره اجرا می‌شود.

۹) چه زمانی باید از React Context در مقابل Redux استفاده کنیم؟

Redux احتمالاً متداول‌ترین کتابخانه سراسری مستقل برای React است، اما می‌توان کلمه “Redux” را با هر کتابخانه سراسری دیگر برای React جایگزین کرد.

React context راهی برای تعریف و استفاده از داده‌ها در سراسر برنامه بدون استفاده از props است.

React context به ما کمک می‌کند تا از مشکل “props drilling” که هنگام انتقال داده‌ها با کامپوننت‌هایی که به آن‌ها نیازی نیست ایجاد می‌شود، جلوگیری کنیم. در عوض، با استفاده از context می‌توانیم داده‌ها را دقیقاً در کامپوننتی که به آن نیاز دارد استفاده کنیم.

در حالی که ما از context فقط برای دریافت یا “خواندن” مقادیر به صورت سراسری در برنامه خود استفاده می‌کنیم، Redux و سایر کتابخانه‌های سراسری امکان خواندن و به‌روزرسانی state را هم به ما می‌دهند.

context جایگزینی برای کتابخانه مستقل مانند Redux نیست زیرا برای به‌روز‌رسانی‌های‌ state ساخته نشده است. چون زمانی که مقادیر ارائه شده در context تغییر کنند، همه childهای آن re-render می‌شوند، که این موضوع می‌تواند به کیفیت عملکرد آسیب برساند.

۱۰) هوک‌های useCallback و useMemo برای چه مواردی استفاده می‌شوند؟

هوک‌های useCallback و useMemo برای بهبود عملکرد کامپوننت‌ها مورد استفاده قرار می‌گیرند.

کاربرد هوک useCallback در React این است که در هر render از ایجاد مجدد توابعی که در بدنه کامپوننت تعریف شده‌اند، جلوگیری کند. این کار می‌تواند منجر به مشکلات عملکرد غیرضروری شود، به خصوص برای توابع callback که به کامپوننت‌های child نیز منتقل می‌شوند.

از طرف دیگر useMemo فرایندهایی که پردازش‌های سنگین دارند را به خاطر می‌سپارد.

Memoization یک اصطلاح فنی برای توابعی است که اگر آرگومان‌هایشان تغییر نکرده باشد، می‌توانند مقادیر گذشته را که محاسبه کرده‌اند “به خاطر بیاورند”. در این صورت، تابع مقدار “یادآوری شده” را برمی‌گرداند.

به عبارت دیگر، ممکن است محاسباتی در برنامه خود داشته باشیم که مقدار قابل توجهی از منابع محاسباتی را مصرف می‌کنند و بخواهیم که تا حد امکان این محاسبات کم انجام شوند. در این صورت، از هوک useMemo استفاده می‌کنیم که با هوک useCallback تفاوت دارد زیرا یک مقدار برمی‌گرداند، نه یک تابع.

 

منبع

دیدگاه‌ها:

افزودن دیدگاه جدید