واکنش: مفاهیم اساسی و بهترین شیوه ها

معرفی
مروری برای تازه کردن دانش شما از عملکرد اصلی React.
بیایید نگاهی به یک برنامه React بیندازیم و راههای بهبود کد را بررسی کنیم.
کد اولیه
export default function App() {
const cars = [
{
name: "Lightning McQueen ⚡️",
image:
"https://i.pinimg.com/1200x/c4/50/07/c45007f8ec1d37926d87befde23ec323.jpg",
},
// ...
];
return (
<div className="App">
<Container cars={cars} />
</div>
);
}
function Container({ cars }) {
let title = "Participants";
const [isTitleUppercase, setTitleUppercase] = useState(false);
const generateExtraParams = () => {
return {
position: 1,
selfConfidence: Infinity,
};
};
const handleClick = () => {
setTitleUppercase((prev) => !prev);
};
return (
<>
<header>
<h1>{isTitleUppercase ? title.toUpperCase() : title}</h1>{" "}
<button onClick={handleClick}>Case toggle 🖲️</button>
</header>
<main>
{cars.map((car, index) => (
<CarCard
key={index}
car={car}
// extraParams={generateExtraParams()}
/>
))}
</main>
</>
);
}
function CarCard({ car, extraParams }) {
console.log(`🏎️ Ka-Chow! ⚡️⚡️⚡️`);
return (
<>
<p>{car.name}</p>
<div id="iw">
<img src={car.image} width={100} />
</div>
{extraParams &&
Object.entries(extraParams).map(([key, value]) => (
<p key={Math.random()}>
<i>{key}:</i> {value}
</p>
))}
</>
);
}
1. جلوگیری از رندرهای غیر ضروری
اکنون، هنگامی که روی دکمه “Case toggle” کلیک می کنیم، آن را می بینیم CarCard
در حال ارائه مجدد است. چرا این اتفاق می افتد و چه کاری می توانیم در مورد آن انجام دهیم؟
این به این دلیل اتفاق میافتد که کنترلکننده دکمه در مؤلفه والد وجود دارد، که باعث رندر مجدد آن مؤلفه و همه فرزندان آن میشود. برای رفع این مشکل می توانیم استفاده کنیم React.memo
برای پیچیدن ما CarCard
جزء. React.memo
کامپوننتی با مرتبه بالاتر است که تنها در صورتی که اجزای بسته بندی شده تغییر کند، دوباره رندر می شود. بدین ترتیب، CarCard
رندر مجدد نمی شود مگر اینکه ویژگی های خاص آن تغییر کند.
در اینجا نحوه اجرای آن آمده است:
const CarCard = React.memo(function ({ car, extraParams }) {
console.log(`🏎️ Ka-Chow! ⚡️⚡️⚡️`);
return (
<>
<p>{car.name}</p>
<div id="iw">
<img src={car.image} width={100} />
</div>
{extraParams &&
Object.entries(extraParams).map(([key, value]) => (
<p key={Math.random()}>
<i>{key}:</i> {value}
</p>
))}
</>
);
});
2. فراخوانی های تابع را به خاطر بسپارید
وقتی خط را از کامنت بردارید extraParams={generateExtraParams()}
و کلیک کنید 'Case toggle' button
، متوجه خواهید شد که CarCard دوباره ارائه می شود. این به این دلیل است که GenererExtraParams یک شی جدید در هر رندر ایجاد می کند و React آن را به عنوان داده جدید در نظر می گیرد.
برای جلوگیری از این، استفاده می کنیم React.useMemo
برای به خاطر سپردن نتیجه generateExtraParams
. این تضمین می کند که تابع فقط یک بار فراخوانی می شود و از همان شی در رندرهای بعدی استفاده می شود و از رندرهای مجدد غیرضروری جلوگیری می کند.
const generateExtraParams = () => {
return {
position: 1,
selfConfidence: Infinity,
};
};
const extraParams = React.useMemo(() => generateExtraParams(), []);
3. یک هوک سفارشی ایجاد کنید
آیا میتوانیم یک قلاب سفارشی برای مدیریت عملکرد جابجایی حروف بزرگ ایجاد کنیم، زیرا ممکن است در آینده در مکانهای مختلف به آن نیاز داشته باشیم؟ کاملا. بیایید آن را پیاده سازی کنیم:
const useToggle = () => {
const [isTitleUppercase, setTitleUppercase] = useState(false);
const toggle = () => {
setTitleUppercase((prev) => !prev);
};
return [isTitleUppercase, toggle];
};
// Inside the Container
const [isTitleUppercase, toggle] = useToggle();
// And use it like this:
<header>
<h1>{isTitleUppercase ? title.toUpperCase() : title}</h1>{" "}
<button onClick={toggle}>Case toggle 🖲️</button>
</header>
حالت و عملکرد را به یک قلاب سفارشی منتقل کردیم که میتوانیم در مکانهای مختلف در صورت نیاز دوباره از آن استفاده کنیم.
4. از Context برای Deep Prop Drilling استفاده کنید
حال، اگر لازم باشد یک پایه را عمیقاً از درخت جزء عبور دهیم، آیا میتوانیم این کار را بهتر از حفاری ساده انجام دهیم؟ بله، ما می توانیم از زمینه برای این استفاده کنیم.
React Context راهی برای مدیریت وضعیت در سطح جهانی است. این به شما امکان می دهد یک شی زمینه ایجاد کنید، که سپس می تواند به درخت مؤلفه ارائه شود. هر مؤلفه ای در درخت می تواند ارزش زمینه را بدون نیاز به عبور از هر سطح مصرف کند.
در اینجا نحوه اجرای آن آمده است:
-
ایجاد زمینه:
ما با استفاده از یک آبجکت زمینه ایجاد می کنیمReact.createContext()
و یک مقدار پیش فرض ارائه دهید. در این صورت، ما زمینه ای برای خودروهای خود ایجاد خواهیم کرد. -
ارائه زمینه:
ما از یک فراهم کننده زمینه برای بسته بندی درخت جزء خود استفاده می کنیم. این باعث می شود که مقدار متن در دسترس همه مؤلفه های موجود در ارائه دهنده باشد. -
زمینه مصرف:
هر مؤلفه ای که به مقدار متن نیاز دارد می تواند از قلاب useContext برای دسترسی به آن استفاده کند.
ما همچنین یک قلاب سفارشی ایجاد می کنیم useCarsContext
برای سهولت در مصرف زمینه. این قلاب فراخوانی useContext را کپسوله میکند، بنابراین نیازی نیست آن را در هر مؤلفهای که به مقدار متن نیاز دارد، تکرار کنیم.
در اینجا نحوه ظاهر کد به روز شده است:
import React, { useMemo, useState, useContext, createContext } from "react";
const CarsContext = createContext([]);
const useCarsContext = () => useContext(CarsContext);
export default function App() {
const cars = [
{
name: "Lightning McQueen ⚡️",
image:
"https://i.pinimg.com/1200x/c4/50/07/c45007f8ec1d37926d87befde23ec323.jpg",
},
// ...
];
return (
<CarsContext.Provider value={cars}>
<div className="App">
<Container />
</div>
</CarsContext.Provider>
);
}
const useToggle = () => {
const [isTitleUppercase, setTitleUppercase] = useState(false);
const toggle = () => {
setTitleUppercase((prev) => !prev);
};
return [isTitleUppercase, toggle];
};
function Container() {
let title = "Participants";
const [isTitleUppercase, toggle] = useToggle();
const generateExtraParams = () => {
return {
position: 1,
selfConfidence: Infinity,
};
};
const extraParams = useMemo(() => generateExtraParams(), []);
const cars = useCarsContext();
return (
<>
<header>
<h1>{isTitleUppercase ? title.toUpperCase() : title}</h1>{" "}
<button onClick={toggle}>Case toggle 🖲️</button>
</header>
<main>
{cars.map((car, index) => (
<CarCard key={index} car={car} extraParams={extraParams} />
))}
</main>
</>
);
}
const CarCard = React.memo(function ({ car, extraParams }) {
console.log(`🏎️ Ka-Chow! ⚡️⚡️⚡️`);
return (
<>
<p>{car.name}</p>
<div id="iw">
<img src={car.image} width={100} />
</div>
{extraParams &&
Object.entries(extraParams).map(([key, value]) => (
<p key={Math.random()}>
<i>{key}:</i> {value}
</p>
))}
</>
);
});
5. از استفاده از Index و Math.random() برای کلیدها خودداری کنید
آخرین پیشرفت: استفاده از index و Math.random() برای کلیدها در لیست ها تمرین خوبی نیست. در عوض، از یک شناسه منحصر به فرد مربوط به مورد استفاده کنید. این تضمین میکند که React میتواند موارد اضافه، جابجا یا حذف شده را به درستی ردیابی کند.
نتیجه
امیدوارم این حافظه شما را در مورد عملکرد اصلی React تازه کند. با بررسی این مثالها و پیشرفتها، دیدیم که چگونه برنامههای React خود را کارآمدتر و نگهداری آسانتر کنیم.
با تشکر برای پاتوق کردن! برای اطلاعات بیشتر اشتراک را بزنید! 👋