🎉 راهنمای مبتدیان برای استفاده از افکت

به دنیای React Hooks خوش آمدید! امروز، ما به یکی از محبوب ترین قلاب ها می پردازیم: useEffect
. نگران نباشید، ما آن را سرگرم کننده و قابل درک می کنیم. بنابراین، بیایید شروع کنیم! 🚀
📚 چیست useEffect
useEffect
هست یک واکنش هوک که به شما اجازه می دهد تا عوارض جانبی را در اجزای عملکردی خود انجام دهید. عوارض جانبی اقداماتی هستند که خارج از مؤلفه شما اتفاق میافتند، مانند واکشی دادهها، بهروزرسانی DOM یا اشتراک در رویدادها. با useEffect
، می توانید این عوارض جانبی را بدون نوشتن کلاس یا تابع مدیریت کنید. 🎉
🧪 چگونه useEffect
آثار
useEffect
مانند یک چاقوی ارتش سوئیس 🇨🇭🔪 برای عوارض جانبی در اجزای عملکردی شماست. ترکیبی از عملکرد componentDidMount
، componentDidUpdate
، و componentWillUnmount
از اجزای کلاس به یک قلاب ساده.
در اینجا نحوه کار آن آمده است:
- شما تماس بگیرید
useEffect
با عملکردی که حاوی عارضه جانبی شماست. - React عملکرد عوارض جانبی شما را پس از رندر کردن کامپوننت اجرا می کند.
- اگر یک تابع پاکسازی ارائه دهید، React آن را زمانی که کامپوننت unmount شده است یا زمانی که وابستگی ها تغییر می کنند، فراخوانی می کند.
نیازی به نوشتن کلاس یا تابع نیست! 🤯
⚡ موارد استفاده مختلف
بیایید برخی از موارد استفاده رایج را بررسی کنیم useEffect
:
-
در حال واکشی داده ها: شما می توانید استفاده کنید
useEffect
برای واکشی داده ها از یک API و به روز رسانی وضعیت مؤلفه خود هنگام دریافت داده ها. 📦 -
به روز رسانی عنوان سند: آیا می خواهید عنوان صفحه وب خود را بر اساس وضعیت جزء تغییر دهید؟
useEffect
برای نجات! 🦸♂️ -
راه اندازی شنوندگان رویداد: آیا نیاز به گوش دادن به رویدادهایی مانند تغییر اندازه پنجره یا ورودی صفحه کلید دارید؟
useEffect
می تواند به شما در راه اندازی و پاکسازی شنوندگان رویداد کمک کند. 🎧 -
حالت ماندگار: آیا می خواهید وضعیت جزء خود را در حافظه محلی یا پایگاه داده ذخیره کنید؟
useEffect
می تواند آن را نیز اداره کند! 💾 -
تایمرها و فواصل: اگر نیاز به تنظیم یک تایمر یا فاصله زمانی در جزء خود دارید،
useEffect
ابزار عالی برای کار است. میتوانید تایمر را هنگامی که مؤلفه نصب میشود شروع کنید و زمانی که مؤلفه جدا میشود، آن را پاک کنید. ⏳
📝 نمونه هایی از موارد استفاده useEffect 📝
مثال 1: واکشی داده ها
FetchData
├── button.tsx
├── location.tsx
├── weather.tsx
```tsx
import React, { useState, useEffect } from "react";
import fetchWeatherData from "./weather"; // Import the function to fetch weather data
interface WeatherProps {
location: string;
}
const WeatherButtons: React.FC<WeatherProps> = ({ location }) => {
const [weatherData, setWeatherData] = useState<any>(null); // Create state to hold weather data and initialize it to null
const [requestType, setRequestType] = useState<string>(""); // Create state to hold the type of request to make and initialize it to an empty string
useEffect(() => {
if (requestType) { // If a request type has been selected
fetchWeatherData(location, requestType).then((data: any) => // Call the function to fetch weather data
setWeatherData(data) // Set the weather data to the response from the API
);
}
}, [requestType, location]); // Run the effect when either request type or location changes
return (
<div className="text-2xl">
<button
className="weather-current-weather-button"
onClick={() => setRequestType("current")} // When the button is clicked, set the request type to "current"
>
Current Weather
</button>
{weatherData && ( // If weather data exists
<div className="weather-json-bg">
<pre className="weather-button-pre-wrap">
{JSON.stringify(weatherData, null, 2)} // Display the weather data as JSON
</pre>
</div>
)}
</div>
);
};
export default WeatherButtons;
این مؤلفه دکمهای را ارائه میکند که با کلیک کردن، دادههای آب و هوا را از API دریافت میکند. دارای ویژگی های زیر است:
- وارد می کند
useState
وuseEffect
قلاب از React، وfetchWeatherData
تابع ازweather.tsx
. - را دریافت می کند
location
prop از مؤلفه والد خود، که شهری را مشخص می کند که داده های آب و هوا برای آن باید واکشی شود. - دو متغیر حالت را با استفاده از
useState
قلاب:weatherData
، که داده های آب و هوای واکشی شده را ذخیره می کند وrequestType
، که تعیین می کند چه نوع داده های آب و هوا واکشی شود (به عنوان مثال، آب و هوای فعلی، پیش بینی 5 روزه). - از
useEffect
قلاب برای واکشی داده های آب و هوا از API زمانی کهrequestType
تغییر می کند (یعنی وقتی دکمه کلیک می شود)، و به روز رسانی می شودweatherData
متغیر حالت با داده های واکشی شده - یک دکمه را با یک رندر می کند
onClick
رویدادی که تعیین می کندrequestType
متغیر حالت به “جریان” (یعنی واکشی داده های آب و هوای فعلی). - اگر
weatherData
تهی نیست، a را ارائه می دهدpre
برچسبی که داده های واکشی شده را در قالب JSON نمایش می دهد.
```tsx
import React, { createContext, useState } from "react";
export const LocationContext = createContext<any>(null); // Create a context object to hold location data
export const LocationProvider: React.FC = ({ children }) => { // Create a provider component for the context
const [location, setLocation] = useState<string>("New York"); // Create state to hold the current location and initialize it to "New York"
const changeLocation = (newLocation: string) => {
setLocation(newLocation); // Function to update the location
};
return (
<LocationContext.Provider value={{ location, changeLocation }}>
{children}
</LocationContext.Provider>
);
};
این مؤلفه زمینه ای ایجاد می کند که مکان فعلی را که باید داده های آب و هوا برای آن واکشی شود، ذخیره می کند. دارای ویژگی های زیر است:
- وارد می کند
createContext
وuseState
قلاب از React. - الف را ایجاد می کند
LocationContext
با استفاده ازcreateContext
قلاب، که برای عبور ازlocation
متغیر حالت وchangeLocation
عملکرد به اجزای فرزند - الف را تعریف می کند
LocationProvider
جزء با استفاده ازuseState
قلاب، که اولیه را تنظیم می کندlocation
متغیر حالت به “نیویورک”. - الف را تعریف می کند
changeLocation
عملکردی که به روز رسانی می کندlocation
متغیر حالت با مکان جدید. - را ارائه می دهد
LocationContext.Provider
جزء باlocation
متغیر حالت وchangeLocation
به عنوان ارزش آن، و اجزای فرزند آن به عنوان فرزندان آن عمل می کند.
```tsx
const fetchWeatherData = async (
location: string,
requestType: string
): Promise<any> => {
const apiKey = process.env.NEXT_PUBLIC_WEATHER ?? ""; // Get the API key from the environment variables
const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${location}&appid=${apiKey}`; // Construct the API URL using the location and API key
const response = await fetch(apiUrl); // Make a request to the API
const data = await response.json(); // Parse the response as JSON
return data; // Return the data
};
export default fetchWeatherData;
این مؤلفه تابعی را تعریف می کند که داده های آب و هوا را از OpenWeatherMap API با استفاده از ارائه شده واکشی می کند location
و requestType
مولفه های. دارای ویژگی های زیر است:
- یک را تعریف می کند
async
تابع فراخوانی شدfetchWeatherData
که می گیردlocation
وrequestType
مولفه های. - این کلید API را از یک متغیر محیطی به نام دریافت می کند
NEXT_PUBLIC_WEATHER
. - URL API را با استفاده از
location
وapiKey
متغیرها و کاربردهاfetch
برای ایجاد یک درخواست GET به API. - از آن استفاده می کند
json
روش شی پاسخ برای تبدیل پاسخ به یک شی جاوا اسکریپت. - داده های واکشی شده را به صورت a برمی گرداند
Promise
.
نحوه استفاده
import WeatherButtons from "../components/react/useEffect/FetchData/button";
import { LocationProvider } from "../components/react/useEffect/FetchData/location";
<LocationProvider>
<WeatherButtons
location="London"
units="metric"
theme="dark"
/>
</LocationProvider>
برای استفاده از این کامپوننت ها می توانید وارد کنید WeatherButtons
و LocationProvider
داخل کامپوننت React خودتان و بسته بندی کنید WeatherButtons
داخل LocationProvider
. سپس شما می توانید در مورد نظر عبور کنید location
(و به صورت اختیاری، units
و theme
) لوازم به WeatherButtons
. هنگامی که دکمه کلیک می شود، داده های آب و هوا برای مکان مشخص شده واکشی شده و در قالب JSON نمایش داده می شود.
مثال 2 – UserFetchData
UserFetch
├── Data.tsx
├── UserFetch.tsx
```tsx
import React, { useEffect, useState } from "react";
// Define the shape of the data object that will be returned by the hook
type Data<T> = {
status: "loading" | "success" | "error";
data?: T;
error?: Error;
};
// Custom hook that fetches data from an API endpoint and returns the data object
export function useFetch<T>(url: string): Data<T> {
// Create a state variable called 'data' and initialize it with { status: "loading" }
const [data, setData] = useState<Data<T>>({ status: "loading" });
// useEffect hook that runs when the URL changes
useEffect(() => {
// Define an asynchronous function called 'fetchData'
const fetchData = async () => {
try {
// Fetch data from the API endpoint
const response = await fetch(url);
const result = await response.json();
// Update the 'data' state variable with the fetched data
setData({ status: "success", data: result });
} catch (error) {
// Update the 'data' state variable with the error object
setData({ status: "error", error: error as Error });
}
};
// Call the 'fetchData' function to fetch data from the API endpoint
fetchData();
}, [url]); // Only run the effect when the url changes
// Return the 'data' object
return data;
}
- را
Data
type شکل شی داده ای را که توسط the برگردانده می شود را مشخص می کندuseFetch
قلاب. این شامل سه ویژگی است:status
،data
، وerror
. - را
useFetch
تابع یک URL را به عنوان پارامتر خود می گیرد و آن را برمی گرداندdata
شیئی که قبلاً تعریف شده بود. - در داخل
useFetch
تابع،useState
برای ایجاد متغیر حالت استفاده می شودdata
و حالت اولیه آن تنظیم شده است{ status: "loading" }
. -
useEffect
برای واکشی داده ها از نقطه پایانی API استفاده می شود. فقط زمانی اجرا می شود که URL تغییر کند زیرا[url]
به عنوان آرگومان دوم آن تصویب می شود. - درون
useEffect
تابع،fetchData
یک تابع ناهمزمان است که استفاده می کندtry
وcatch
بلوک ها برای واکشی داده ها از نقطه پایانی API. اگر واکشی موفقیت آمیز باشد،setData
تابع با فراخوانی می شود{ status: "success", data: result }
. اگر خطایی وجود داشته باشد،setData
تابع با فراخوانی می شود{ status: "error", error: error as Error }
. - سرانجام،
useFetch
را برمی گرداندdata
هدف – شی.
```tsx
import React, { useState } from "react";
import { useFetch } from "./Data";
function UsersFetch() {
// Create a state variable called 'url' and initialize it with the API endpoint URL
const [url, setUrl] = useState("https://jsonplaceholder.typicode.com/users");
// Call the 'useFetch' hook with the 'url' state variable
const data = useFetch<Array<{ id: number; name: string }>>(url);
// Render a button that changes the 'url' state variable when clicked
return (
<div>
<button
className="user-fetch-button"
onClick={() => setUrl(url + "?_limit=5")}
>
Fetch only 5 users
</button>
{/* If the 'status' property of the 'data' object is 'loading', render a loading message */}
{data.status === "loading" && <p>Loading...</p>}
{/* If the 'status' property of the 'data' object is 'success', render a list of users */}
{data.status === "success" && (
<ul className="user-fetch-data-bg">
{data.data?.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)}
{/* If the 'status' property of the 'data' object is 'error', render an error message */}
{data.status === "error" && <p>Error: {data.error?.message}</p>}
</div>
);
}
export default UsersFetch;
- را
UsersFetch
تابع یک جزء React است که ازuseFetch
برای واکشی داده ها از نقطه پایانی API و رندر کردن آن، قلاب کنید. - جزء استفاده می کند
useState
برای ایجاد یک متغیر حالتurl
با مقدار اولیه"https://jsonplaceholder.typicode.com/users"
. - را
data
به متغیر نتیجه فراخوانی اختصاص داده می شودuseFetch
قلاب باurl
. - دکمه ای ارائه می شود که تماس می گیرد
setUrl
با یک URL جدید هنگام کلیک کردن. - کامپوننت بسته به نوع محتوای متفاوتی ارائه می دهد
status
دارایی ازdata
هدف – شی. - اگر
status
است"loading"
، کامپوننت پیام بارگیری را ارائه می دهد. - اگر
status
است"success"
، کامپوننت لیستی از کاربران را با نام آنها ارائه می دهد. - اگر
status
است"error"
، کامپوننت یک پیام خطا با پیام شی خطا ارائه می دهد.
مثال 3 – ویجت
Widget
├── ColorWidget.tsx
├── Widget.tsx
```tsx
// This function creates a new widget element with the specified background color and adds it to the provided container element.
export function createWidget(color: string, container: HTMLElement) {
// Create a new div element to serve as the widget.
const widget = document.createElement("div");
// Set the widget's background color.
widget.style.background = color;
// Set the widget's width and height.
widget.style.width = "100px";
widget.style.height = "100px";
// Set the widget's border radius.
widget.style.borderRadius = "25%";
// Set the widget's margin.
widget.style.margin = "10px";
// Set the widget's border style and color.
widget.style.border = "2px solid pink";
// Create a new custom event to be dispatched periodically by the widget.
const statusChangeEvent = new CustomEvent("statusChange", {
detail: { status: "active" },
});
// Set an interval to dispatch the statusChangeEvent every 1000 milliseconds (1 second).
setInterval(() => {
widget.dispatchEvent(statusChangeEvent);
}, 1000);
// Add the widget to the container element.
container.appendChild(widget);
// Return an object with functions to add and remove event listeners, as well as to destroy the widget.
return {
addEventListener: widget.addEventListener.bind(widget),
removeEventListener: widget.removeEventListener.bind(widget),
destroy: () => container.removeChild(widget),
};
}
- خط 1: یک تابع به نام تعریف کنید
createWidget
که دو آرگومان می گیردcolor
(رشته) وcontainer
(HTMLElement). - خط 2-9: یک جدید ایجاد کنید
div
عنصر با ارائه شدهcolor
، اندازه، شکل، حاشیه و حاشیه آن را تنظیم کنید. - خط 11-15: یک رویداد سفارشی جدید به نام ایجاد کنید
statusChangeEvent
با یکdetail
دارایی حاوی{ status: "active" }
. - خط 17-20: اعزام
statusChangeEvent
در هر ثانیه. - خط 22: ضمیمه کنید
widget
بهcontainer
. - خط 24-29: یک شی که دارای سه ویژگی است را برگردانید:
addEventListener
،removeEventListener
، وdestroy
.
```tsx
import React, { useEffect, useRef, useState } from "react";
import { createWidget } from "./Widget";
interface ColorWidgetProps {
initialColor: string;
}
const ColorWidget: React.FC<ColorWidgetProps> = ({ initialColor }) => {
// useRef hook to create a reference to the container div element
const containerRef = useRef<HTMLDivElement>(null);
// useState hook to create a state variable for the color of the widget
const [color, setColor] = useState(initialColor);
// useEffect hook to run side-effects when the component mounts or the color state changes
useEffect(() => {
// Get the current value of the container reference
const container = containerRef.current;
// If the container exists, create a widget and add event listeners to it
if (container) {
// Create the widget with the given color and container
const widget = createWidget(color, container);
// Define a function to handle the "statusChange" event of the widget
const handleStatusChange = (event: CustomEvent<{ status: string }>) => {
console.log("The status is:", event.detail.status);
};
// Add an event listener to the widget to listen for "statusChange" events
(widget as any).addEventListener("statusChange", handleStatusChange);
// Return a cleanup function to remove the widget and event listeners when the component unmounts or the color changes
return () => {
widget.destroy();
(widget as any).removeEventListener("statusChange", handleStatusChange);
};
}
}, [color]);
// Define a function to update the color state variable with a random hex color
const changeColor = () => {
setColor(
`#${Math.floor(Math.random() * 0x1000000)
.toString(16)
.padStart(6, "0")}`
);
};
// Render the ColorWidget component with a container div, a button to change the color, and the color widget itself
return (
<div className="color-widget">
<div className="widget-container" ref={containerRef}></div>
<button className="widget-button" onClick={changeColor}>
Change Color
</button>
</div>
);
};
export default ColorWidget;
- خط 1-8: وابستگی های لازم را وارد کنید و یک رابط برای آن تعریف کنید
ColorWidgetProps
. - خط 10-18: یک جزء کاربردی به نام تعریف کنید
ColorWidget
که طول می کشدinitialColor
به عنوان یک پایه و مقداری JSX را برمی گرداند. - خط 19: با استفاده از یک مرجع ایجاد کنید
useRef
برای ذخیره یک مرجع به adiv
عنصر - خط 21-23: حالتی به نام تعریف کنید
color
استفاده كردنuseState
و آن را با مقداردهی اولیه کنیدinitialColor
. - خط 25-47: استفاده کنید
useEffect
برای ایجاد یک ویجت با استفاده ازcreateWidget
، شنونده رویداد را به آن اضافه کنید، و ویجت و شنونده رویداد را پاک کنیدcolor
تغییر کند یا کامپوننت خارج شود. - خط 33-39: یک تابع فراخوانی را تعریف کنید
changeColor
که یک رنگ هگزا دسیمال تصادفی تولید می کند و آن را به عنوان رنگ جدید تنظیم می کندcolor
. - خط 42-46: مقداری JSX را که حاوی الف است برگردانید
div
با یکref
به مرجع ظرف، یک دکمه با یکonClick
کنترل کننده رویداد که تماس می گیردchangeColor
و برخی از کلاسهای CSS برای استایلسازی.
مثال 4 – اثر شرطی
```tsx
import React, { useState, useEffect } from "react";
export const ConditionalEffect: React.FC = () => {
// state variables for count and message
const [count, setCount] = useState(0);
const [message, setMessage] = useState("");
// useEffect hook that runs whenever count changes
useEffect(() => {
// check if count is even or odd
if (count % 2 === 0) {
// set message to "Even" if count is even
setMessage("Even");
} else {
// set message to "Odd" if count is odd
setMessage("Odd");
}
}, [count]);
// render the component with a button that increments count on click
// also display the current message and count value
return (
<div>
<button
className="conditional-effect-button"
onClick={() => setCount(count + 1)}
>
Conditional Effect
</button>
<p className="conditional-effect-text">{message}</p>
<p className="conditional-effect-text">Count: {count}</p>
</div>
);
};
-
import React, { useState, useEffect } from "react";
: React و قلاب های useState و useEffect را وارد می کندreact
کتابخانه -
const [count, setCount] = useState(0);
: یک متغیر حالت را اعلام می کندcount
با استفاده از قلاب useState با مقدار اولیه 0 و یک تابعsetCount
که به ما امکان می دهد تا به روز رسانی کنیمcount
متغیر. -
const [message, setMessage] = useState("");
: یک متغیر حالت را اعلام می کندmessage
با استفاده از قلاب useState با مقدار اولیه یک رشته خالی و یک تابعsetMessage
که به ما امکان می دهد تا به روز رسانی کنیمmessage
متغیر. -
useEffect(() => {...}, [count]);
: افکتی را تعریف می کند که هر زمان اجرا شودcount
تغییرات متغیر حالت اگرcount
یکنواخت است،message
روی “زوج” تنظیم می شود، در غیر این صورت روی “فرد” تنظیم می شود. -
<button className="conditional-effect-button" onClick={() => setCount(count + 1)}>Conditional Effect</button>
: یک دکمه را با یک کنترل کننده کلیک ارائه می دهد که آن را به روز می کندcount
متغیر حالت هنگام کلیک کردن -
<p className="conditional-effect-text">{message}</p>
: مقدار را ارائه می دهدmessage
. -
<p className="conditional-effect-text">Count: {count}</p>
: مقدار را ارائه می دهدcount
.
مثال 5 – اثر تایمر
```tsx
import React, { useState, useEffect } from "react";
export const Timer: React.FC = () => {
// Set the initial state of seconds to 0 using useState hook
const [seconds, setSeconds] = useState(0);
useEffect(() => {
// Set an interval to increment seconds state by 1 every 1000ms using setInterval
const interval = setInterval(() => {
setSeconds((seconds) => seconds + 1);
}, 1000);
// Clear the interval using clearInterval in the cleanup function
return () => {
clearInterval(interval);
};
}, []); // Effect only runs once (empty dependency array)
return (
<div>
<p className="timer-text">
You have been on this page for {seconds} seconds.
</p>
</div>
);
};
-
import React, { useState, useEffect } from "react";
: اجزای React لازم را وارد کنید. -
const [seconds, setSeconds] = useState(0);
: یک متغیر حالت را اعلام کنیدseconds
و عملکرد به روز رسانی مربوطه آنsetSeconds
، مقداردهی اولیه به0
. -
useEffect(() => {...}, []);
: ازuseEffect
قلاب برای اجرای یک اثر جانبی پس از رندر اولیه و اجرای پاکسازی قبل از unmount. آرایه وابستگی خالی است، بنابراین افکت فقط یک بار پس از رندر اولیه اجرا می شود. -
const interval = setInterval(() => {...}, 1000);
: فاصله ای را برای افزایش آن تنظیم کنیدseconds
در هر ثانیه 1 حالت دهید. -
setSeconds((seconds) => seconds + 1);
: به روز رسانی کنیدseconds
با تابع updater حالت دهید تا مقدار آن 1 افزایش یابد. -
return () => {...};
: یک تابع پاکسازی را برای پاک کردن فاصله زمانی که مؤلفه جدا شده است، برگردانید. -
<p className="timer-text">You have been on this page for {seconds} seconds.</p>
: رندر یک عنصر پاراگراف که نشان می دهدseconds
متغیر حالت
مثال 6 – عنوان را به روز کنید
```tsx
import React, { useEffect, useState } from "react";
export function UpdateTItle() {
const [count, setCount] = useState(0); // create a state variable 'count' and its update function 'setCount' with an initial value of 0
useEffect(() => {
// This is a side effect that runs when the component mounts, and whenever 'count' changes
// It updates the document title with the current count
document.title = `You clicked ${count} times`;
}, [count]); // Only run the effect when 'count' changes
return (
<div>
<p className="update-title-text">You clicked {count} times</p>
<button
className="update-title-button"
onClick={() => setCount(count + 1)}
>
Click me
</button>
</div>
);
}
- کد یک کامپوننت تابعی React به نام را تعریف می کند
UpdateTitle
. - کامپوننت یک متغیر حالت را مقداردهی اولیه می کند
count
با مقدار اولیه 0 و تابع به روز رسانی مربوطه آنsetCount
. - را
useEffect
از قلاب برای ایجاد یک اثر جانبی استفاده می شود که هنگام سوار شدن مؤلفه و هر زمان که اجرا می شودcount
تغییر می کند. - در داخل افکت، عنوان سند با مقدار فعلی به روز می شود
count
درون یک رشته - را
useEffect
hook آرایه ای از وابستگی ها را به عنوان آرگومان دوم خود می گیرد. وقتی هر یک از وابستگی ها تغییر کرد، افکت دوباره اجرا می شود. در این مورد، اثر فقط به این بستگی داردcount
، بنابراین فقط زمانی اجرا می شودcount
تغییر می کند. - کامپوننت یک div حاوی یک عنصر پاراگراف را برمی گرداند که مقدار فعلی آن را نمایش می دهد
count
و دکمه ای که به روز می شودcount
هنگام کلیک کردن
خودشه! اکنون شما درک کاملی از آن دارید useEffect
و چگونه می تواند به شما در مدیریت وضعیت در اجزای عملکردی React کمک کند. کد نویسی مبارک! 🎉