


آموزش کاربردی React Hooks از صفر تا صد
هوکها به عنوان یک توسعهدهنده اپ این امکان را فراهم میکنند که از ویژگیهای بیشتر در React استفاده کنید؛ ویژگیهایی مانند مدیریت state کامپوننت یا اجرای افتر افکت زمانی که تغییرات خاصی در state ها بدون نوشتن کلاس رخ میدهد.
هوکها برای اولین بار در نسخه React 16.8 معرفی شدند. هوکها به عنوان یک توسعهدهنده اپ این امکان را فراهم میکنند که از ویژگیهای بیشتر در React استفاده کنید؛ ویژگیهایی مانند مدیریت state کامپوننت یا اجرای افتر افکت زمانی که تغییرات خاصی در state ها بدون نوشتن کلاس رخ میدهد.
هوکها توابعی هستند که از کامپوننتهای تابع به ویژگیهای React مانند state و lifecycle متصل میشوند. هوکها دارای ویژگی سازگاری پسین هست، به این معنی که تغییرات و بهروزرسانیها روی آنها تأثیری نداشته و به مرور با ارائه نسخههای بهروزرسانی شده React، جایگزین نمیشوند. هرگاه بخواهید یک کامپوننت تابع را بنویسید و یک یا چند state را به آن اضافه کنید، قبلاً این کار با تبدیل کامپوننت به یک کلاس انجام میگرفت. اما امروزه میتوان با استفاده از هوک داخل کامپوننت تابع مورد نظر، این کار را انجام داد.
دو قانون مهم در هوک های React
هوکها شبیه توابع جاوا اسکریپت هستند، اما هنگام استفاده از آنها باید چند قانون را رعایت کنید. رعایت این قوانین تضمین میکند که عملگرهای منطقی در یک کامپوننت در کد منبع آن قابلمشاهده باشند. این قوانین عبارتاند از:
1. هوکها تنها در سطح بالا فراخوانی میشوند.
هوکها را درون حلقهها، کدهای شرطی یا توابع تودرتو فراخوانی نکنید. هوکها باید همیشه در سطح بالای توابع React استفاده شوند. این قانون تضمین میکند هر بار که یک کامپوننت رندرگیری میشود، هوکها به ترتیب رندرگیری، فراخوانی شوند.
2. هوکها فقط از توابع React فراخوانی میشوند.
نمیتوان هوکها را از توابع معمولی جاوا اسکریپت فراخوانی نمود. در مقابل، میتوان هوکها را از کامپوننتهای تابع React فراخوانی کرد. هوکها را میتوان از هوکهای سفارشی نیز فراخواند. برای اجرای هوکهای React چند پیشنیاز اصلی وجود دارد:
• Node نسخه 6 یا بالاتر
• NPM نسخه 5.2 یا بالاتر
• ابزار Create-react-app برای اجرای اپ React
مزایای استفاده از هوک چیست؟
سادهترین راه برای توصیف هوکها این است که هوکها نشاندهنده نمونههای مرتبطی از یک کامپوننت کلاس هستند که باید به متدهای state و lifecycle دسترسی داشته باشد.
هوکها برای توسعهدهندگان فواید زیادی دارند به گونهای که نحوه نوشتن کامپوننتها را تغییر میدهند. هوکها امکان توسعه کدهای واضحتر و مختصرتر را فراهم میکنند. تغییر کدها به کمک هوک میتواند تأثیر قابلتوجهی بر حجم و خوانایی کد داشته باشد.
ویژگی اصلی هوکها این است که با کدهای جایگزین خود سازگاری دارند، به این معنی که نیازی به تغییر پایگاه کد وجود نداشته و تنها حجم کدها را میتوان کاهش داد.
نصب هوکهای React چگونه است؟
برای استفاده از هوکهای React ابتدا میبایست دستورات زیر را اجرا کنید:
$ npm install react@16.8.0-alpha.1 --save $ npm install react-dom@16.8.0-alpha.1 --save
دستور بالا آخرین نسخههای React و React-DOM آلفا را که از React Hooks پشتیبانی میکنند نصب خواهد کرد. اول همه باید مطمئن شوید که فایل package.json از dependency های React و React-DOM پشتیبانی کرده و به آنها دسترسی دارد یا خیر.
برای این منظور دستورات زیر را اجرا نمایید:
"react": "^16.8.0-alpha.1", "react-dom": "^16.8.0-alpha.1",
پرکاربردترین هوکها کدماند؟
هوکهای useState، useEffect و useContext پرکاربردترین هوکها هستند که به ترتیب با کلاسهای React local state، effects و context کار میکنند.
برخی دیگر از هوکهای مورد استفاده در React عبارتاند از:useReducer, useCallback, useMemo, useRef, useImperativeHandle, useLayoutEffect and useDebugValue.
در ادامه پرکاربردترین هوکهای React را معرفی کرده و نحوه استفاده از آنها را بررسی خواهیم کرد.
هوک useState چیست؟
وضعیت اپلیکیشن در برخی مواقع تغییر میکند. این تغییرات میتواند در مقدار یک متغیر، یک آبجکت یا هر نوع دادهای باشد که در کامپوننت مورد نظر وجود دارد. برای اینکه بتوانیم تغییرات را در DOM منعکس کنیم، باید از یک هوک React به نام useState استفاده نماییم. نمونهای از بهکارگیری هوک useState به صورت زیر است:
import { useState } from "react"; function App() { const [name, setName] = useState("Ihechikara"); const changeName = () => { setName("Chikara"); }; return ( <div> <p>My name is {name}</p> <button onClick={changeName}> Click me </button> </div> ); } export default App;
حال تکتک مراحل را در کد بالا بررسی میکنیم. در دستور اول به منظور استفاده از هوک useState، میبایست این هوک از React ایمپورت شود. برای این منظور از یک کامپوننت تابع تحت عنوان app() استفاده میکنیم.
پس از آن باید وضعیت یا state را ایجاد کرده و یک مقدار اولیه (یا حالت اولیه) مانند «Ihechikara» برای آن تعریف کنید. متغیر حالت name بوده و setName نیز تابع مربوط به آن و یا تابع بهروزرسانی مقدار آن است.
در ادامه، DOM دارای یک پاراگراف حاوی متغیر name و یک button است که با کلیک کردن، تابع را فعال میکند. تابع changeName تابع setName را فراخوانی میکند که در ادامه مقدار متغیر name را به مقدار ارسال شده به تابع setName تغییر میدهد.
چگونه میتوان از هوک useState در فرم استفاده کرد؟
این بخش به شما کمک میکند تا چگونگی تعریف مقادیر state را برای فرمها یاد گرفته و در صورت نیاز آنها را بهروزرسانی کنید. این روند با آنچه در بخش قبل دیدیم تفاوت چندانی ندارد. برای شروع مثل همیشه، هوک useState را ایمپورت کنید.
import { useState } from "react";
state اولیه را مانند قبل ایجاد کنید. اما در این حالت یک رشته خالی تعریف کنید زیرا با مقدار یک المان ورودی سروکار داریم.
const [name, setName] = useState("")
پس از ایجاد state، المان ورودی را در DOM ایجاد کرده و متغیر name را به عنوان مقدار اولیه آن اختصاص دهید. به صورت زیر:
return ( <div> <form> <input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder="Your Name" /> <p>{name}</p> </form> </div> );
متوجه خواهید شد که تابعی در بالای عبارت return برای بهروزرسانی مقدار state ایجاد نشده است اما اگر تصمیم به استفاده از این روش داشته باشید، اشکالی ندارد. در اینجا، از onChange استفاده میکنیم که هرگونه تغییر مقدار در فیلد ورودی را تشخیص میدهد.
هر زمان که تغییری در مقدار state رخ دهد، یک تابع ناشناس (که آبجکت رویداد را به عنوان پارامتر ورودی میگیرد) اجرا شده و سپس تابع setName() را فراخوانی میکند تا متغیر name را با مقدار فعلی فیلد ورودی جایگزین نماید.
هوک useEffect چیست؟
هوک Effect، درست همانطور که از نامش پیداست، هر بار که یک state تغییر کند، یک افکت ایجاد میکند. به طور پیشفرض، پس از اولین رندرگیری و هر بار که state بهروزرسانی میشود، این هوک اجرا میگردد. در مثال زیر یک تعداد متغیر state با مقدار اولیه صفر ایجاد میکنیم.
یک button در DOM قرار خواهیم داد که هر بار که روی آن کلیک میشود، مقدار این متغیر را یک عدد افزایش دهد. هوک useEffect هر بار که متغیر count تغییر میکند اجرا شده و برخی از اطلاعات را به کنسول ارسال میکند.
import { useState, useEffect } from "react"; function App() { const [count, setCount] = useState(0); useEffect(() => { console.log(`You have clicked the button ${count} times`) }); return ( <div> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ); } export default App;
اولین خط کدی که در آن هوکهای مورد نیاز را ایمپورت میکنید، از اهمیت بالایی برخوردار است. در کد فوق، دو هوک ایمپورت شدهاند که عبارتاند از: useState و useEffect. توجه داشته باشید که میتوان از هوک useEffect برای دستیابی به افکتهای مختلفی مانند fetching دادهها از یک API خارجی، تغییر DOM در کامپوننت مورد نظر و غیره استفاده کرد.
اگر بخواهید افکت شما فقط بعد از اولین رندرگیری اجرا شود، یا اگر چندین state داشته باشید و فقط یک افتر افکت به یکی از state ها متصل گردد، چه کاری باید انجام داد؟ خیلی ساده است، تنها با استفاده از یک آرایه dependency که به عنوان آرگومان دوم در هوک useEffect تعریف میشود، میتوان این اقدامات را انجام داد.
هوک useContext چیست؟
هوک useContext برای ایجاد دادههای مشترک استفاده میشود که میتوان در سرتاسر سلسلهمراتب کامپوننتها بدون انتقال پروبها به صورت دستی به هر سطح به آن دسترسی داشت. به جای انتقال پروبها از هر کامپوننت در مسیر پایین، میتوان آنها را در کامپوننت والد تعریف کرد.
به این ترتیب میتوان کامپوننتهای میانی را که نیازی به آنها نیست، دور زده و حجم کد را کاهش داد. در یک کد React میتوان Context را داخل یک کامپوننت کلاس و یا داخل یک کامپوننت تابع با استفاده از هوک useContext به کار برد.
مثال زیر، استفاده از Context را در داخل کامپوننت کلاس نشان میدهد:
import AppContext from './appContext.js'; class Example extends React.Component { static context = AppContext; render() { let value = this.context; ... } }
همچنین مثال زیر استفاده از آبجکت Context را داخل کامپوننت تابع با استفاده از هوک useContext نمایش میدهد:
import AppContext from './appContext.js'; const Example = () => { const context = useContext(AppContext); return ( ... ); }
یک Context هم یک consumer و هم یک provider را فراهم میکند. میتوان با استفاده از React.CreateContext یک آبجکت Context در React ایجاد نموده و سپس مقدار اولیه آن را ارسال کرد، به صورت زیر:
const AppContext = React.createContext({ foo: 'bar' });
آبجکت AppContext همان آبجکتی است که باید به عنوان یک آرگومان به useContext Hook ارسال شود. به شکل زیر:
const context = useContext(AppContext);
چگونه هوک اختصاصی بسازیم؟
اکنون که برخی از پرکاربردترین هوکهای داخلی را در React شناختیم وقت آن است که هوک سفارشی خود را ایجاد کنیم. برای ایجاد قابلیتهای هوک سفارشی، روشهای مختلفی وجود دارد. در این بخش، ایجاد یک هوک سفارشی را که بتواند دادهها را از یک API خارجی fetche کرده و دادهها را به DOM ارسال کند، توضیح خواهیم داد.
گام 1: ایجاد فایل
هنگام ایجاد یک فایل جدید برای یک هوک سفارشی، همیشه مطمئن شوید که نام فایل با "use" شروع شود. ما نام فایل خود را useFetchData.js انتخاب میکنیم.
گام 2: ایجاد عملکردهای هوک
همانطور که قبلاً گفته شد، ما از این هوک برای fetche کردن دادهها از API های خارجی استفاده میکنیم. در ادامه نحوه انجام این کار آمده است:
import { useState, useEffect} from 'react' function useFetchData(url) { const [data, setData] = useState(null); useEffect(() => { fetch(url) .then((res) => res.json()) .then((data) => setData(data)) .catch((err) => console.log(`Error: ${err}`)); }, [url]); return { data }; } export default useFetchData
توضیح آنچه در بالا اتفاق افتاده است به صورت زیر است:
• ابتدا هوکها را ایمپورت کردیم: import { useState, useEffect} from 'react'
• سپس یک state ایجاد کردهایم تا دادههایی را که برگردانده میشوند، نگهداری کند - state اولیه null خواهد بود: const [data, setData] = useState(null);. دادههای برگشتی با استفاده از تابع setData() مقدار متغیر data را بهروزرسانی میکنند.
• سپس یک افکت ایجاد میکنیم که در اولین رندرگیری و هر بار که پارامتر url تغییر میکند، اجرا شود.
useEffect(() => { fetch(url) .then((res) => res.json()) .then((data) => setData(data)) .catch((err) => console.log(`Error: ${err}`)); }, [url]);
گام 3 : یک فایل جدید ایجاد کرده و هوک سفارشی خود را ایمپورت کنید
حالا وقت آن رسیده است که یک کامپوننت جدید ایجاد کرده و عملکرد هوک useFetchData را برای آن بررسی کنیم:
import useFetchData from './useFetchData' function Users() { const { data } = useFetchData("https://api.github.com/users"); return ( <div> {data && ( data.map((user) =>( <div className="text-white" key={user.id}> <h1> {user.login} </h1> <p> { user.type } </p> </div> )) )} </div> ) } export default Users;
تجزیه و تحلیل کد بالا به صورت زیر است:
• ابتدا کامپوننت را با نام Users.js تعریف کرده زیرا برای fetching دادههای کاربر از API GitHub استفاده میکند.
• سپس هوک سفارشی را ایمپورت میکنیم:import useFetchData from './useFetchData'.
• با عملکرد هوک پیش از بازگشت state و ارسال URL، یک درخواست API به هر URL ی ارسالی، فرستاده خواهد شد: const { data } = useFetchData("https://api.github.com/users");.
• با استفاده از عملگر &&، DOM فقط زمانی بهروزرسانی میشود که متغیر Data با دادههای درخواست API بهروزرسانی گردد، یعنی زمانی که data != null شود.
• به این ترتیب، از طریق دادههای برگشتی یک حلقه ایجاد شده و متغیر Data به DOM ارسال شده است.
جمعبندی
اگر تا این مرحله با ما همراه بودهاید، باید درک خوبی از هوکها در React، نحوه استفاده از آنها و نحوه ایجاد هوکهای سفارشی کسب کرده باشید. بهترین راه برای درک کامل این موضوع تمرین است، پس فقط به مطالعه اکتفا نکنید. این مقاله مفاهیم اصلی مرتبط با هوکها را پوشش میدهد، اما برای آشنایی بیشتر و درک مفاهیم عمیقتر توصیه میکنیم نمونههای دیگری از هوکها و استفاده از آنها را مطالعه کنید.