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

به دنیای 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. - را دریافت می کند
locationprop از مؤلفه والد خود، که شهری را مشخص می کند که داده های آب و هوا برای آن باید واکشی شود. - دو متغیر حالت را با استفاده از
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;
}
- را
Datatype شکل شی داده ای را که توسط 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درون یک رشته - را
useEffecthook آرایه ای از وابستگی ها را به عنوان آرگومان دوم خود می گیرد. وقتی هر یک از وابستگی ها تغییر کرد، افکت دوباره اجرا می شود. در این مورد، اثر فقط به این بستگی داردcount، بنابراین فقط زمانی اجرا می شودcountتغییر می کند. - کامپوننت یک div حاوی یک عنصر پاراگراف را برمی گرداند که مقدار فعلی آن را نمایش می دهد
countو دکمه ای که به روز می شودcountهنگام کلیک کردن
خودشه! اکنون شما درک کاملی از آن دارید useEffect و چگونه می تواند به شما در مدیریت وضعیت در اجزای عملکردی React کمک کند. کد نویسی مبارک! 🎉



