برگه تقلب React

1074
برگه تقلب React

در این مقاله قصد داریم تا با ارائه‌ی یک برگه تقلب React، مروری سریع بر تمامی مفاهیم و نحوه‌ی کار با کتابخانه‌ی React.js داشته باشیم.

خب بیایید بدون مقدمه‌چینی شروع کنیم:

عناصر (React Elements)

عناصر React، کاربردی مانند عناصر Html دارند و شما می‌توانید از تمامی عناصر Html در React استفاده کنید.

<h1>My Header</h1>
<p>My paragraph</p>
<button>My button</button>

در React این عناصر به‌وسیله‌ی ابزاری به نام JSX نوشته می‌شوند. همچنین به‌دلیل اینکه JSX در حقیقت توابع جاوااسکریپتی هستند، نحوه‌ی نگارش (Syntax) کمی با Html تفاوت دارد. برای مثال بر‌خلاف Html تگ‌های منفرد (Single Tags) باید به‌وسیله‌ی «/» بسته شوند:

<img src="my-image.png" />
<br />
<hr />

ویژگی عناصر (React Element Attributes)

همچنین در JSX برای تعیین ویژگی عناصر باید به‌طرز متفاوتی نسبت به Html رفتار کنیم. چون JSX در حقیقت جاوااسکریپت است و جاوااسکریپت از قاعده‌ی camelCase پیروی می‌کند. بنابراین، ویژگی‌ها متفاوت از Html نوشته می‌شوند. مثال رایج این موضوع ویژگی class است که به‌صورت className نوشته می‌شود:

<div className="container"></div>

استایل عناصر (React Element Styles)

برای اعمال‌کردن استایل خطی بر روی عناصر مختلف باید به‌جای استفاده از دابل کوتیشن “” از دو براکت تو‌در‌تو {{}} استفاده کنیم:

<h1 style={{ fontSize: 24, margin: '0 auto', textAlign: 'center' }}>My header</h1>

React Fragments

در React می‌توان از عنصری به‌نام Fragment استفاده کرد. در React قانونی وجود دارد که می‌گوید تمامی عناصر باید زیرمجموعه‌ی یک عنصر والد (Parent) باشند. برای مثال ما نمی‌توانیم دو عنصر h1 و p را هم‌زمان به‌وسیله‌ی یک کامپوننت بازگردانی (return) کنیم:

// اینگونه ساختار اشتباه است
function MyComponent() {
  return (
    <h1>My header</h1>
    </p>My paragraph</p>
  );
}

اگر نمی‌خواهیم برای حل این مشکل از عناصری مانند div استفاده کنیم، می‌توانیم از Fragment‌ها استفاده کنیم که به دو صورت زیر استفاده می‌شوند:

// اولین نوع استفاده
<> ... </>
// دومین نوع استفاده
<Fragment> ... </Fragment>

برای مثال قبل:

// ساختار صحیح
function MyComponent() {
  return (
    <>
      <h1>My header</h1>
      </p>My paragraph</p>
    </>
  );
}

React Components

در React می‌توانیم به‌وسیله‌ی کامپوننت‌ها مجموعه‌ای از عناصر را مدیریت کنیم. یک نوع ساده از کامپوننت‌های تابعی (function component) همانند توابع جاوااسکریپت است با چند تفاوت زیر:

  1. اسامی باید با حروف بزرگ شروع شوند (Mycomponent به‌جای mycomponent)
  2. کامپوننت‌ها لزوماً باید مقدار JSX را بازگردانی (return) کنند.

مثال:

function App() {
  return (
     <div>Hello world!</div>
  );
}

React Props

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

در مثال زیر ما مقدار name را از کامپوننت App به کامپوننت User ارسال می‌کنیم:

function App() {
  return <User name="Mohammadreza Babayi" />
}

function User(props) {
  return <h1>Hello, {props.name}</h1>; // Hello, Mohammadreza Babayi!
}

همچنین همان طور که در مثال بالا دیدیم، برای استفاده از یک مقدار غیرثابت در JSX باید از براکت استفاده کرد. با این روش می‌توانیم تمامی مقادیر جاوااسکریپتی از جمله دیگر عناصر و کامپوننت‌ها را به یک کامپوننت ارسال کنیم.

React Children Props

همچنین می‌توان داده‌ها را با قراردادن آن‌ها بین تگ‌های کامپوننت ارسال کرد.

مثال:

function App() {
  return (
   <User>
     <h1>Hello, Mohammadreza Babayi!</h1>
   </User>
  );
}

function User({ children }) {
  return children; // Hello, Mohammadreza Babayi!
}

شروط در React

در React می‌توان عناصر و کامپوننت‌ها را به‌صورت شرطی نمایش داد. روش اول برای این کار استفاده از بازگردانی (return) شرطی به‌وسیله‌ی if می‌باشد.

function App() {
  const isAuthUser = useAuth();

  if (isAuthUser) {
    // اگر کاربر وارد شده بود اجازه استفاده بده
    return <AuthApp />;
  }

  // اگر کاربر وارد نشده بود اجازه استفاده را نده
  return <UnAuthApp />;
}

همچنین می‌توان به‌وسیله‌ی عملگر شرطی سه‌تایی این کار را به‌صورت مستقیم در JSX انجام داد:

function App() {
	const isAuthUser = useAuth();

  return (
    <>
      <h1>My App</h1>
      {isAuthUser ? <AuthApp /> : <UnAuthApp />}
    </>
  ) 
}

لیست‌ها در React

لیستی از کامپوننت‌ها را می‌توان به‌عنوان خروجی نمایش داد. تابع ()map. می‌تواند بر روی آرایه‌ای از داده پیمایش کرده و آن را بر روی JSX اعمال کند. برای نمونه در مثال زیر، لیستی از اسامی فوتبالیست‌ها را نمایش می‌دهیم:

function SoccerPlayers() {
  const players = ["Messi", "Ronaldo", "Laspada"];

  return (
    <div>
      {players.map((playerName) => (
        <SoccerPlayer key={playerName} name={playerName} />
      ))}
    </div>
  );
}

هر زمان که روی مجموعه‌ای از عناصر پیمایش می‌کنید، باید کلید (key) منحصر‌به‌فردی را به هر یک از عناصر ساخته‌شده در JSX اختصاص دهید. در این مثال ما از نام بازیکنان استفاده کردیم.

React Context

مفهوم context جهت به اشتراک گذاشتن داده‌ها به‌صورت سراسری بین کامپوننت‌های با ساختار درختی (tree child) و جلوگیری از props‌های تو‌در‌تو (props drilling) می‌باشد.

در صورتی از این ویژگی استفاده می‌کنیم که ساختار درختی کامپوننت‌ها سه لایه یا بیشتر باشد. برای استفاده از این ویژگی از تابع createContext در React استفاده می‌کنیم. همچنین از Provider برای تعریف مقادیری که می‌خواهیم به‌صورت سراسری قابل‌دسترسی باشند و از Consumer نیز برای استفاده از آن‌ها استفاده می‌کنیم.

به مثال زیر توجه کنید:

import { createContext } from 'react';

const NameContext = createContext('');

function App() {
  return (
    <NameContext.Provider value="Mohammadreza Babayi">
      <Body />
    <NameContext.Provider>
  );
} 

function Body() {
  return <Greeting />;
} 

function Greeting() {
  return (
    <NameContext.Consumer>
      {name => <h1>Welcome, {name}</h1>}
    </NameContext.Consumer>
  );
}

React Hooks

هوک قابلیت جدیدی است که از نسخه 16.8 به React اضافه شد و امکان استفاده از state و دیگر قابلیت‌های React را بدون استفاده از کلاس کامپوننت‌ها (Class Components)‌ ممکن می‌سازد. همچنین ما می‌توانیم هوک‌های اختصاصی خودمان را بسازیم تا به‌وسیله‌ی آن‌ها ویژگی‌هایی را در برنامه‌ی خود ایجاد کنیم.

ممکن است علاقه‌مند باشید: نحوه‌ی کار Hook‌ها در React به زبان ساده

هوک‌های زیادی به هسته‌ی اصلی کتابخانه React افزوده شدند، اما ما در اینجا تنها به معرفی مهم‌ترین آن‌ها می‌پردازیم:

  • useState
  • useEffect
  • useRef
  • useContext
  • useCallback

useState Hook

این هوک برای استفاده از state‌ها (مقادیری که با تغییر آن‌ها کامپوننت دوباره رندر می‌شود) کاربرد دارد. دلیل رایج استفاده از این ویژگی آن است که بتوانیم تغییرات انجام‌شده بر روی مقادیر را مشاهده کنیم.

import { useState } from 'react';

function MyComponent() {
  const [stateValue, setStateValue] = useState(initialValue);
}

می‌توان مقدار اولیه‌ای را به‌وسیله‌ی این هوک به state خود اختصاص داده و سپس به‌وسیله‌ی stateValue به مقدار state دسترسی پیدا کرده و به‌وسیله‌ی تابع setStateValue مقدار state را تغییر داد.

یک مثال ساده برای استفاده از useState ساخت یک شمارنده است:

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  function updateCount() {
    setCount(count + 1);
  }

  return <button onClick={updateCount}>Count is: {count}</button>;
}

در اینجا می‌توان به‌وسیله‌ی count مقدار فعلی را مشاهده کرده و به‌وسیله‌ی setCount مقدار قبلی را تغییر داد.

useEffect Hook

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

import { useEffect } from 'react';

function MyComponent() {
   useEffect(() => {
     // تعاملات و اثرات را میتوان در اینجا اعمال نمود
   }, []);
}

برای مثال هنگام بارگذاری اطلاعات از این هوک استفاده می‌کنیم. در مثال زیر پست‌هایی را بارگذاری می‌کنیم و سپس آن‌ها را نمایش می‌دهیم‌:

import { useEffect } from 'react';

function PostList() {
	 const [posts, setPosts] = useState([]);

   useEffect(() => {
	   fetch('https://api.yoursiteurl.com/posts')
       .then(response => response.json())
       .then(posts => setPosts(posts));
   }, []);

   return posts.map(post => <Post key={post.id} post={post} />
}

وقتی می‌خواهیم از مقداری بیرونی استفاده کنیم، باید آن را در آرایه‌ی وابستگی‌های useEffect قرار دهیم. در این صورت هنگامی که آن مقدار تغییر کند، تابع useEffect دوباره اجرا خواهد شد.

برای مثال می‌توانیم از مقداری به‌نام open استفاده کنیم تا هنگامی که منوی موبایل باز و بسته شد، کلاس overflow-hidden را به بدنه‌ی JSX اضافه نماید:

function Mobile({ open }) {
  useEffect(() => {
    const body = document.querySelector("#__next");

    if (open) {
      body.classList.add("overflow-hidden");
    } else {
      body.classList.remove("overflow-hidden");
    }
  }, [open]);
 
  // ...
}

useRef Hook

این هوک به ما قابلیت دسترسی مستقیم به یک عنصر JSX را می‌دهد. برای استفاده از این هوک باید آن را صدا بزنید و نتیجه که یک اشاره‌گر (Reference) می‌باشد را به عنصر مورد‌نظر اختصاص دهید.

نحوه استفاده از این هوک را در مثال زیر می‌بینید:

import { useRef } from 'react';

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

  return <div ref={ref} />
}

به محض اینکه ref به عنصر خودش متصل شد، می‌توانیم به‌وسیله‌ی ref.current از آن استفاده کنیم. برای مثال وقتی بخواهیم برنامه‌ای بنویسیم که هنگامی که کاربر کلید‌های Ctrl + K را فشرد، سرچ‌بار به حالت فوکوس درآید از این هوک استفاده می‌کنیم:

import { useWindowEvent } from "@mantine/hooks";
import { useRef } from "react";

function Header() {
  const inputRef = useRef();

  useWindowEvent("keydown", (event) => {
    if (event.code === "KeyK" && event.ctrlKey) {
      event.preventDefault();
      inputRef.current.focus();
    }
  });
  
  return <input ref={inputRef} />
}

useContext Hook

به‌وسیله‌ی این هوک می‌توان از روشی بسیار ساده‌تر از Context.Consumer به مقادیر سراسری دسترسی پیدا کرد. با این هوک می‌توانیم نام Context موردنظر را صدا بزنیم. مقداری که برگردانده (return) می‌شود، مقدار مورد‌نظر ما خواهد بود.

import { useContext } from 'react';

function MyComponent() {
  const value = useContext(Context);

  // ...
}

برای نمونه می‌توانیم مثالی را که در بخش Context نمایش دادیم با این هوک بازنویسی کنیم:

import { createContext, useContext } from 'react';

const NameContext = createContext('');

function App() {
  return (
    <NameContext.Provider value="Mohammadreza Babayi">
      <Body />
    <NameContext.Provider>
  );
} 

function Body() {
  return <Greeting />;
} 

function Greeting() {
	const name = useContext(NameContext);

  return (
    <h1>Welcome, {name}</h1>
  );
}

useCallback Hook

این هوک ابزاریست برای افزایش بهره‌وری (Performance) برنامه‌ی ما، به این صورت که از ساخته‌شدن مجدد توابع هنگامی که کامپوننت ما دوباره پردازش می‌شود جلوگیری می‌کند.

برای نمونه در مثال PlayerList اگر ما قابلیت افزودن بازیکن را به آن اضافه کنیم و برای حذف آن تابعی را (handleRemovePlayer) از طریق props به آن پاس دهیم، هربار این تابع از ابتدا ساخته خواهد شد. برای جلوگیری از این اتفاق، کافیست از useCallback استفاده کرده و این تابع را داخل آن قرار دهیم و تنها آرگومان وابسته را در وابستگی‌ها بگذاریم:

function App() {
  const [player, setPlayer] = React.useState("");
  const [players, setPlayers] = React.useState(["Messi", "Ronaldo", "Laspada"]);

  function handleChangeInput(event) {
    setPlayer(event.target.value);
  }
  function handleAddPlayer() {
    setPlayers(players.concat(player));
  }
  const handleRemovePlayer = useCallback(player => {
    setPlayers(players.filter((p) => p !== player));
  }, [players])

  return (
    <>
      <input onChange={handleChangeInput} />
      <button onClick={handleAddPlayer}>Add Player</button>
      <PlayerList players={players} handleRemovePlayer={handleRemovePlayer} />
    </>
  );
}

function PlayerList({ players, handleRemovePlayer }) {
  return (
    <ul>
      {players.map((player) => (
        <li key={player} onClick={() => handleRemovePlayer(player)}>
          {player}
        </li>
      ))}
    </ul>
  );
}

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

محمدرضا بابایی

سلام ، من محمدرضام و علاقه بسیار زیادی به آموختن و آموزش دارم. امیدوارم نوشته‌هام برای شما جالب و مفید باشن :)

اشتراک در
اطلاع از
guest

2 دیدگاه‌
قدیمی‌ترین
تازه‌ترین بیشترین واکنش
بازخورد (Feedback) های اینلاین
View all comments
فرزان رحمانی
16 روز قبل

خیلی مفید و کاربردی بود به خصوص قسمت هوک هاش فقط قسمت آخرش که callback بود رو اگه مثال بدون callback هم میذاشتی فهمش بهتر میشد.😅❤

آخرین ویرایش16 روز قبل توسط فرزان رحمانی