با قلابهای مربوط به عملکرد React 18، میتوانید بهروزرسانیهای حالت را سرعت بخشیده و همزمانی را در برنامههای خود بهبود بخشید.
در مارس 2022، تیم React انتشار رسمی React 18 را اعلام کرد. این نسخه با مجموعه ای از ویژگی های جدید با هدف بهبود عملکرد، مبتنی بر مفهوم “رندر همزمان” ارائه شد. ایده پشت رندر همزمان این است که فرآیند رندر به DOM قطع شود.
در میان ویژگیهای جدید پنج هوک وجود دارد: useId، useTransition، useDerredValue، useSyncExternalStore و useInsertionEffect.
React useTransition Hook
بهطور پیشفرض، همه بهروزرسانیهای React State فوری هستند. به روز رسانی های مختلف در برنامه شما برای منابع یکسان با هم رقابت می کنند و سرعت آن را کاهش می دهند. قلاب useTransition React این مشکل را حل میکند و به شما اجازه میدهد برخی بهروزرسانیهای وضعیت را بهعنوان غیر فوری علامتگذاری کنید. این به بهروزرسانیهای حالت فوری اجازه میدهد تا موارد با اولویت پایینتر را قطع کند.
جزء جستجوی صفحه
این برنامه ساده از موتور جستجویی تقلید می کند که دو حالت را به روز می کند – یک فیلد ورودی و برخی از نتایج جستجو.
import { useState } from "react";
function SearchPage() {
const [input, setInput] = useState("")
const [list, setList] = useState([]);
const listSize = 30000
function handleChange(e) {
setInput(e.target.value);
const listItems = [];
for (let i = 0; i < listSize; i++){
listItems.push(e.target.value);
}
setList(listItems);
}
return (
<div>
<label>Search the Web: </label>
<input type="text" value={input} onChange={handleChange} />
{list.map((item, index) => {
return <div key={index}>{item}</div>
})}
</div>
);
}
export default SearchPage;
جزء برنامه به روز شده
import SearchPage from "./Components/SearchPage";
function App() {
return (
<div>
< SearchPage/>
</div>
);
}
export default App;
کد بالا یک برنامه React را با یک فیلد ورودی ارائه می کند:
وقتی شروع به تایپ کاراکترها در فیلد می کنید، 30000 کپی از متن تایپ شده در زیر ظاهر می شود:
اگر چندین کاراکتر را پشت سر هم تایپ کنید، باید یک تاخیر را تشخیص دهید. بر زمان ظاهر شدن کاراکترها هم در قسمت ورودی و هم در «ناحیه نتیجه جستجو» تأثیر میگذارد. این به این دلیل است که React هر دو به روز رسانی حالت را همزمان اجرا می کند.
اگر نسخه آزمایشی برای شما خیلی کند یا خیلی سریع اجرا می شود، سعی کنید آن را تغییر دهید
اندازه لیست
بر این اساس ارزش گذاری کنید.
قرار دادن قلاب useTransition در برنامه به شما این امکان را می دهد که به روز رسانی یک وضعیت را بر دیگری اولویت بندی کنید.
با استفاده از useTransition Hook
import {useState, useTransition} from "react";
function SearchPage() {
const [isPending, startTransition] = useTransition();
const [input, setInput] = useState("")
const [list, setList] = useState([]);
const listSize = 30000
function handleChange(e) {
setInput(e.target.value);
startTransition(() => {
const listItems = [];
for (let i = 0; i < listSize; i++){
listItems.push(e.target.value);
}
setList(listItems);
});
}
return (
<div>
<label>Search the Web: </label>
<input type="text" value={input} onChange={handleChange} />
{isPending ? "...Loading results" : list.map((item, index) => {
return <div key={index}>{item}</div>
})}
</div>
);
}
export default SearchPage;
بهروزرسانی مؤلفه SearchPage با کد بالا، فیلد ورودی را بر «ناحیه نتایج جستجو» اولویتبندی میکند. این تغییر ساده تأثیر واضحی دارد: شما باید بلافاصله متنی را که تایپ میکنید در قسمت ورودی مشاهده کنید. فقط “ناحیه نتایج جستجو” هنوز کمی تاخیر خواهد داشت. این به دلیل رابط برنامه نویسی startTransitionApplication (API) از قلاب useTransition است.
کدی که نتایج جستجو را به UI ارائه می کند اکنون از startTransition API استفاده می کند. این به فیلد ورودی اجازه میدهد تا بهروزرسانی وضعیت نتایج جستجو را قطع کند. هنگامی که تابع isPending() “…نتیجه بارگیری” را نمایش می دهد، نشان می دهد که یک انتقال (از یک حالت به حالت بعدی) در حال انجام است.
React useDeferredValue Hook
قلاب useDeferredValue به شما این امکان را می دهد که رندر مجدد یک به روز رسانی حالت غیر ضروری را به تعویق بیندازید. مانند قلاب useTransition، قلاب useDeferredValue یک قلاب همزمانی است. قلاب useDeferredValue به یک حالت اجازه می دهد تا مقدار اصلی خود را در زمانی که در حال انتقال است حفظ کند.
جزء SearchPage با قلاب useDeferredValue().
import { useState, useTransition, useDeferredValue } from "react";
function SearchPage() {
const [,startTransition] = useTransition();
const [input, setInput] = useState("")
const [list, setList] = useState([]);
const listSize = 30000
function handleChange(e) {
setInput(e.target.value);
startTransition(() => {
const listItems = [];
for (let i = 0; i < listSize; i++){
listItems.push(e.target.value);
}
setList(listItems);
});
}
const deferredValue = useDeferredValue(input);
return (
<div>
<label>Search the Web: </label>
<input type="text" value={input} onChange={handleChange} />
{list.map((item, index) => {
return <div key={index} input={deferredValue} >{item}</div>
})}
</div>
);
}
export default SearchPage;
در کد بالا خواهید دید که تابع ()isPending دیگر وجود ندارد. این به این دلیل است که متغیر deferredValue از قلاب useDeferredValue جایگزین تابع isPending() در طول انتقال حالت می شود. به جای اینکه لیست نتایج جستجو هنگام تایپ یک کاراکتر جدید به روز شود، تا زمانی که برنامه وضعیت را به روز کند، مقادیر قدیمی خود را حفظ می کند.
React useSyncExternalStore Hook
برخلاف قلابهای useTransition و useDeferredValue که با کد برنامه کار میکنند، useSyncExternalStore با کتابخانهها کار میکند. این به برنامه React شما اجازه می دهد تا در کتابخانه های خارجی مشترک شود و داده ها را بخواند. قلاب useSyncExternalStore از اعلان زیر استفاده می کند:
const state = useSyncExternalStore(subscribe, getSnapshot[, getServerSnapshot]);
این امضا شامل موارد زیر است:
- state: مقدار ذخیره داده ای که قلاب useSyncExternalStore برمی گرداند.
- اشتراک: زمانی که ذخیره داده تغییر می کند، یک تماس برگشتی ثبت می کند.
- getSnapshot: مقدار فعلی ذخیره اطلاعات را برمی گرداند.
- getServerSnapshot: عکس فوری استفاده شده در هنگام رندر سرور را برمی گرداند.
با useSyncExternalStore، می توانید در کل یک فروشگاه داده یا یک فیلد خاص در یک فروشگاه داده مشترک شوید.
React useInsertionEffect Hook
قلاب useInsertionEffect یکی دیگر از قلاب های React جدید است که با کتابخانه ها کار می کند. با این حال، به جای ذخیرهسازی داده، قلاب useInsertionEffect با کتابخانههای CSS-in-JS کار میکند. این قلاب به مشکلات عملکرد رندر سبک می پردازد. قبل از خواندن طرح بندی در قلاب useLayoutEffect، DOM را استایل می کند.
React useId Hook
شما از قلاب useId در موقعیت هایی استفاده می کنید که به شناسه های منحصر به فرد نیاز دارند (به جز کلیدهای موجود در لیست). هدف اصلی آن تولید شناسه هایی است که در بین کلاینت و سرور منحصر به فرد باقی می مانند و از خطای عدم تطابق هیدراتاسیون سرور React جلوگیری می کند. قلاب useId از اعلان زیر استفاده می کند:
const id = useId()
در شناسه اعلان یک رشته منحصر به فرد است که شامل : نشانه است. پس از اعلان، می توانید متغیر id را مستقیماً به عنصر یا عناصری که به آن نیاز دارند، منتقل کنید.
این قلاب های جدید چه ارزشی به واکنش می دهند؟
قلاب های useTransition و useDeferredValue قلاب های کد برنامه هستند. آنها از طریق رندر همزمان، عملکرد برنامه ها را بهبود می بخشند. قلاب useId با ایجاد شناسههای منحصربهفرد در بین کلاینت و سرور، خطای عدم تطابق هیدراتاسیون را برطرف میکند.
قلابهای useSyncExternalStore و useInsertionEffect با کتابخانههای خارجی کار میکنند تا رندر همزمان را تسهیل کنند. قلاب useInsertionEffect با کتابخانه های CSS-in-JS کار می کند. قلاب useSyncExternalStore با کتابخانه های ذخیره داده مانند فروشگاه Redux کار می کند.
این قلابها با هم باعث افزایش عملکرد میشوند که به نوبه خود تجربه کاربر را بهبود میبخشد.