10æ25æ¥ãReactã®æ°æ©èœã§ããConcurrent Modeã®ãã¬ãã¥ãŒçãçºè¡šãããŸããããã®äžã«ã¯ãConcurrent Modeã®æ©æµãåŸãããã«å¿ èŠãšãªãæ°ããAPIãå«ãŸããŠããŸãã
ãããã®APIã®äžå¿ãšãªãã®ããSuspenseãš2çš®é¡ã®æ°ããããã¯useTransitionãšuseDeferredValueã§ãããã®èšäºã§ã¯ãã®2çš®é¡ã®ããã¯ã«çŠç¹ãåœãŠãŠãããããäœãããŠãããã®ããã©ã®ããã«ããããæ°ããã®ãã解説ããŸãã
èŠããã«ãReactã®å ¬åŒããã¥ã¡ã³ããèªãã§ãŸãšããŸãããšããããšã§ããç¹ã«ãã¬ã€ããäžéãèªãã§çè§£ããªããšãããã®ããã¯ãäœãããŠããã®ãçè§£ãã«ãããããæéã§çè§£ã§ããããã«èŠç¹ããŸãšãçŽããŸããã
ãªããåœè©²ããã¥ã¡ã³ãã®æåã«ã§ãã§ããšæžããŠããããã«ããããã®APIã¯ãŸã ãã¬ãã¥ãŒçã§ããããã®èšäºã«æžããŠããããšãããŸã£ããå¥ç©ã«å€åããå¯èœæ§ãããããŸãããã ãå°ãªããšããããã®APIã®åºãšãªãææ³ã«ã€ããŠã¯ä»ã®ãã¡ã«çè§£ããŠãããŠæã¯ãªãã§ãããã
以äžã§ã¯ããã€ãäŸãåºãŠããŸããããããã®äŸã¯ä»¥äžã®ãªããžããªã§å
¬éããŠããŸããnpm startã§percelã®ãµãŒããŒãç«ã¡äžããã®ã§é©åœã«è©ŠããŠã¿ãŠãã ããã
3è¡ã§ãŸãšãããš
æéãšãã£ãŠãããããé·ããªã£ãŠããŸã£ãã®ã§3è¡ãŸãšããçšæããŸããã
- Reactãã¬ã³ããªã³ã°ãäžæããã䞊è¡å®è¡ã§ããããã«ãªãã
-
useTransitionã¯ã¹ããŒã倿Žåãšå€æŽåŸãåæã«ã¬ã³ããªã³ã°ããããšãã«äœ¿ããã -
useDeferredValueã¯å€ã®é·ç§»ãããæãã«é å»¶ããŠã»ãããšãã«äœ¿ããã
Suspenseã®åºç€
ããŠãã§ã¯è§£èª¬ã«å ¥ã£ãŠãããŸãã
ãã ãæ¬é¡ã«å
¥ãåã«Suspenseã®åºç€ã«ã€ããŠçè§£ããŠããã ãå¿
èŠããããŸããä»å解説ããããã¯ïŒç¹ã«useTransitionïŒãSuspenseã«æ·±ãé¢é£ãããã®ã§ãã以äžããã¯ä»æ¹ããããŸãããããç¥ã£ãŠãããšããæ¹ã¯æ¬é¡ã®ããã¯ãæéã§çè§£ããããã«æ¬¡ã®ç¯ãŸã§é£ã°ããŸãããã
以äžã§è§£èª¬ããå 容ãä»åã®ãã¬ãã¥ãŒçã§ã¯ãããŠå©çšå¯èœã«ãªã£ããã®ã§ãããã³ã³ã»ããèªäœã¯åã ããå ¬éãããŠããŸããã®ã§ç¥ã£ãŠããæ¹ãããããšæããŸãã
Suspenseã®æå€§ã®ç¹åŸŽã¯ã³ã³ããŒãã³ããPromiseãæãããšããããšã§ãã
Promiseãæããã³ã³ããŒãã³ã
ã§ã¯ãæåã®äŸãèŠãŸããããäžèšã®ãªããžããªãåãããŠããæ¹ã¯ãã01 Example of Suspenseããšããéšåã§ãã
ãã®äŸã¯èªã¿èŸŒã¿ã«æéããããã³ã³ãã³ãã衚瀺ãããšããç¶æ³ãæ³å®ããåçŽãªäŸã§ããã远å ã³ã³ãã³ãã衚瀺ããšæžããããã¿ã³ã衚瀺ãããŠãããæŒããšãLoading...ããšãã衚瀺ã«åãæ¿ãããŸããããã«2ç§åŸããå€éšããèªã¿èŸŒãã äœããã®ããŒã¿ããšããæååã衚瀺ãããŸãã
ã³ãŒããååãšåŸåã«åããŠç€ºããŸãã
export const Example01 = () => {
const [showChild, setShowChild] = useState(false);
return (
<>
<h1>01 Example of Suspense</h1>
{showChild ? (
<Suspense fallback={<p>loading...</p>}>
<AdditionalContents />
</Suspense>
) : (
<button onClick={() => setShowChild(true)}>远å ã³ã³ãã³ãã衚瀺</button>
)}
</>
);
};
ããã¯äœã®å€å²ããªãã³ã³ããŒãã³ãã§ãã远å ã³ã³ãã³ãã衚瀺ããã¿ã³ãæŒããšshowChildãšããã¹ããŒããtrueã«åãæ¿ãã£ãŠ<AdditionalContents />ã衚瀺ãããŸããä»åãã®åšããSuspenseã§å²ãã§ããŸãã
ãã®AdditionalContentsã¯è¿œå ã³ã³ãã³ãã衚瀺ããã³ã³ããŒãã³ããªã®ã§ããã远å ã³ã³ãã³ãã¯ãã¿ã³ãæŒããŠããããŠã³ããŒãããå¿
èŠããããšããããšã«ããŸãããããã¡ããããŠã³ããŒãã«ã¯æéãããããŸãããã®ã³ã³ããŒãã³ãã¯ä»¥äžã®ããã«äœããŸããã
const AdditionalContents = () => {
// ããŒã¿ãããŒãããŠãã®ããŒã¿ã衚瀺
const data = getData();
return <p>{data}</p>;
};
let loadedData: string | null = null;
// ååŸããããŒã¿ãè¿ã颿°
// ïŒãŸã ååŸããŠããªããšãã¯ååŸãã€ã€Promiseãæãã
const getData = () => {
if (loadedData) {
// ååŸæžã¿ãªã®ã§è¿ã
return loadedData;
} else {
throw loadData(0).then(data => {
loadedData = data;
});
}
};
AdditionalContentsã³ã³ããŒãã³ãã¯getData颿°ãåŒã³åºããŠããŒã¿ãååŸããŸããè¿ãå€ã¯æååã§ããgetData颿°ã¯ããäžã§å®çŸ©ãããŠããŸãã
ä»åã¯ææãã®å®è£
ãªã®ã§loadedDataãšããã°ããŒãã«å€æ°ããããããŒã¿ã®ããŒããå®äºããå Žåã¯ããã«ããŒã¿ãå
¥ã£ãŠããŸããgetDataã¯ãã®loadedDataãååšããŠããã°ãããçŽæ¥è¿ããŸãã
ããŒã¿ããŸã ããŒããããŠããªãå Žåãåé¡ã§ãããã®å Žåã¯loadData颿°ãåŒã³åºããŠããŒã¿ãèªã¿èŸŒã¿ãŸããloadDataã¯Promise<string>ãè¿ãã®ã§ãããŒã¿ãæ¥ãããããloadedDataã«ä»£å
¥ããŸãã
ãããŸã§ã¯è¯ãã®ã§ãããäœãthrowãšãããæ§æãèŠããŸãããå®ã¯ããã¯PromiseãthrowããŠããŸãããšããã®ããloadedData(0).then(...)ãšããã®ã¯Promiseãè¿ãããã§ãã
ãã®Promiseãthrowãããšããã®ãSuspenseæå€§ã®ç¹åŸŽã§ããã³ã³ããŒãã³ãã®ã¬ã³ããªã³ã°äžã«Promiseãthrowãããå Žåã¯ãã¬ã³ããªã³ã°ããµã¹ãã³ããããïŒä»ã¯ãŸã ã¬ã³ããªã³ã°ã§ããªãïŒãšããæ±ãã«ãªããŸãããªãPromiseãthrowããã®ããšããã°ãããã®Promiseã解決ããããããäžå詊ããŠãããããšããææè¡šç€ºã®ããã§ãã
ä»åã®å ŽåãgetDataã¯ãŸã ããŒã¿ãèªã¿ããŸããŠããªãå ŽåããããŒã¿ã®èªã¿èŸŒã¿ãå®äºããã解決ãããPromiseããæããŸããããã«ãããããŒã¿ãèªã¿ããŸãããããäžåºŠã³ã³ããŒãã³ããã¬ã³ããªã³ã°ãããããšãæåŸ
ãããŸãããã®ãšãå床getDataãåŒã°ããŸããããã®å Žåã¯ãã§ã«ããŒã¿ãããããå床Promiseãthrowããå¿
èŠã¯ãããŸããã
Suspenseã«ãããã©ãŒã«ããã¯
ããŠãã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããããšãããPromiseãæããããŠããŸããŸãããããã§ã¯ã¬ã³ããªã³ã°çµæãååšããªãã®ã§ã³ã³ããŒãã³ããã¬ã³ããªã³ã°ã§ããŸããã
ããã«å¯Ÿå¿ããã®ããŸãã«Suspenseã³ã³ããŒãã³ãã®åœ¹å²ã§ããã³ã³ããŒãã³ãã®ã¬ã³ããªã³ã°ããµã¹ãã³ãããå Žåããããå²ãSuspenseã®äžèº«å
šäœããã©ãŒã«ããã¯UIïŒSuspenseã«fallback={...}ã§æž¡ãããã®ïŒã«åãæ¿ãããŸãã
ãã¿ã³ãæŒããç¬éã«ãLoading...ããšãã衚瀺ãåºãã®ã¯ãã®ããã§ããããã§ã¯ã以äžã®ããšãèµ·ãã£ãŠããŸãã
- ãã¿ã³ãæŒããããšã§
setShowChild(true)ãå®è¡ãããshowChildãtrueã«ãªãã -
Example02ãåã¬ã³ããªã³ã°ãããããã«äŒŽã£ãŠ<AdditionalContents />ãã¬ã³ããªã³ã°ãããã -
AdditionalContentsã®ã¬ã³ããªã³ã°ããµã¹ãã³ãããïŒPromiseãæããããïŒã -
Suspenseãããã«åå¿ããŠfallbackã®å 容ãã¬ã³ããªã³ã°ãããã - ãLoading...ããšè¡šç€ºãããã
ãã®åŸã¯ãloadData(0)ã2ç§ã§è§£æ±ºãããããã«ãªã£ãŠããã®ã§ïŒå
·äœçãªå®è£
ã¯ãµã³ãã«ã®ãªããžããªãã芧ãã ããïŒ2ç§åŸã«<AdditionalContents />ãåã³ã¬ã³ããªã³ã°ãããŸããä»åã¯ãµã¹ãã³ãããªããããSuspenseã®ãã©ãŒã«ããã¯ã¯æ¶ããŠäžèº«ãã¡ãããšã¬ã³ããªã³ã°ãããŸãã
以äžãSuspenseã®åºæ¬æ©èœã§ãããèªè
ã®äžã«ã¯ããããªã®ãããã«å¥œããªç¶æ
管çã©ã€ãã©ãªãå
¥ãããããããã°ã§ããã§ããðPromiseãthrowãããªããŠæå³äžæãªããšããæå³ãªããªãïŒð
ããšæã£ãæ¹ãããã§ããããäœãisLoadingã¿ãããªã¹ããŒããçšæããã°åãããšãã§ããŸãããã
ããã«å¯Ÿããçãã¯ããããã説æããããã¯ãéããŠæããã«ãªããŸãã
ã§ã¯ãããããæ¬é¡ã«å ¥ããŸãããã
useTransition
useTransitionããã¯ã¯ãåé ã§è¿°ã¹ãããã«2ã€ã®ç¶æ
ãåæã«ã¬ã³ããªã³ã°ããããšãå¯èœã«ããããã¯ã§ãããšã¯ãã£ãŠãã2ã€ã®ç¶æ
ãåæã«DOMã«åæ ããããã«ã¯ãããŸãããããæ£ç¢ºã«èšãã°ããã®ããã¯ã¯åã®ç»é¢ãDOMã«æ®ããªããè£ã§æ¬¡ã®ç»é¢ã®ã¬ã³ããªã³ã°ãæºåãããšããæåããããããŸããä»åçšæããäŸã¯ãã¡ãã§ãã
export const Example02 = () => {
const [showChild, setShowChild] = useState(false);
// ããã§useTransitionã䜿çš
const [startTransition, isPending] = useTransition({
timeoutMs: 10000 // ã¿ã€ã ã¢ãŠãã10ç§ã«èšå®
});
return (
<>
<h1>02 Example of useTransition</h1>
<Suspense fallback={<p>loading...</p>}>
{showChild ? (
<AdditionalContents />
) : (
<button
onClick={() => {
// setShowChildãstartTransitionã§å²ãã
startTransition(() => {
setShowChild(true);
});
}}
>
远å ã³ã³ãã³ãã衚瀺
</button>
)}
</Suspense>
</>
);
};
AdditionalContentsã®äžèº«ã¯ãã£ããšåããªã®ã§çç¥ããŸããããŸããSuspenseã®äœçœ®ãéœåã«ãã倿ŽããŠããŸãïŒAdditionalContentsã®åšãã§ã¯ãªãæ¡ä»¶åå²å
šäœãå²ãããã«ãçç±ã¯åŸè¿°ïŒã
ãã®ãµã³ãã«ã¯ãå ã»ã©ãšã¯å°ãç°ãªãæåãããŸãããšããã®ããã远å ã³ã³ãã³ãã衚瀺ããã¿ã³ãæŒããŠããLoading...ãã衚瀺ãããŸããã代ããã«ã2ç§åŸãŸã§ã远å ã³ã³ãã³ãã衚瀺ããã¿ã³ã衚瀺ããç¶ãããã®åŸçŽæ¥ããŒã¿ã衚瀺ãããŸãã
å
ã»ã©ãšåããããªæ§æãªã®ã«ãã®ãããªæåã®éããçããã®ã¯ããã¡ããuseTransitionã®ãããã§ãã
useTransitionã®æ©èœ
useTransitionã¯ãstartTransition颿°ãåŸãã®ãäž»èŠãªæ©èœã§ããäžã®ã³ãŒããèŠããšããã²ãšã€isPendingãšãããã®ãååŸããŠããŸãããããã¯ããšã§è§£èª¬ããŸãã
startTransition颿°ã¯ãã³ãŒã«ããã¯é¢æ°ã§ã¹ããŒãã®æŽæ°ãã©ããããããšã§å¹æãçºæ®ããŸããå
·äœäŸã¯ãã¿ã³ã®onClickãã³ãã©ã®å
éšã§äœ¿çšãããŠããŸãã
startTransitionå
éšã§ã¹ããŒããæŽæ°ãããå Žåããã®ã¹ããŒãæŽæ°ã«ãã£ãŠåŒãèµ·ããããåã¬ã³ããªã³ã°ããµã¹ãã³ãããå Žåã¯ãã©ãŒã«ããã¯ã衚瀺ãã代ããã«ä»ã®ç¶æ
ã衚瀺ãç¶ããŸãã
ã€ãŸããä»åã®ãµã³ãã«ã®åäœã¯ä»¥äžã®ããã«èª¬æã§ããŸãã
- ãã¿ã³ãæŒããããšã§
setShowChild(true)ãå®è¡ãããshowChildãtrueã«ãªãã -
Example02ãåã¬ã³ããªã³ã°ãããããã«äŒŽã£ãŠ<AdditionalContents />ãã¬ã³ããªã³ã°ãããã -
AdditionalContentsã®ã¬ã³ããªã³ã°ããµã¹ãã³ãããïŒPromiseãæããããïŒã - ãµã¹ãã³ããçºçããããã
useTransitionã®å¹æã«ããä»ã®ç¶æ ïŒsetShowChild(true);ãããåã®ç¶æ ïŒãDOMã«ç¶æãããã
3ãŸã§ã¯åãšåãã§ãããuseTransitionã®å¹æã«ãã4ã§éãããšãèµ·ãããŸããsetShowChild(true);ãå®è¡ããã«ãé¢ãããããã®åã®ç¶æ
ã衚瀺ããç¶ããã®ã§ãã
ãããŠããµã¹ãã³ãããŠããAdditionalContentsãã¬ã³ããªã³ã°å®äºããæç¹ã§æ°ããç¶æ
ïŒsetShowChild(true);åŸã®ç¶æ
ïŒã衚瀺ãããŸãã
ã¡ãªã¿ã«ãuseTransitionã«ã¯timeoutMsãšãããªãã·ã§ã³ãæž¡ãããŠããŸãïŒããã©ã«ãã¯å€å500ããªç§ãããã§ãïŒãããã¯ãåã®ç»é¢ã衚瀺ãç¶ããé床æéã§ãããã®æéãè¶
ããŠãã³ã³ããŒãã³ãããµã¹ãã³ããããŠããå Žåã¯ã諊ããŠã¹ããŒãæŽæ°åŸã®ç¶æ
ã衚瀺ãããŸãïŒãã ããäŸç¶ãšããŠãµã¹ãã³ãããŠããã³ã³ããŒãã³ããããããåŸæ¥éãSuspenseã«ãããã©ãŒã«ããã¯ã衚瀺ãããŸãïŒã
ãŸããSuspenseã®äœçœ®ãå€åŽã«ç§»åããçç±ã§ãããshowChildã®å€ã«é¢ãããSuspenseãååšããããã«ããããã§ããã©ããããããŸã§èª¬æããuseTransitionã®æ©èœã¯Suspenseã®ããŠã³ãæã«ã¯åããªãããã§ããã€ãŸããuseTransitionå
ã§ã®ã¹ããŒãæŽæ°ã«ãã£ãŠSuspenseãæ°èŠã«èšçœ®ãããå Žåã¯åŸæ¥éããã©ãŒã«ããã¯ã衚瀺ãããæåãšãªããŸãã
æãããSuspenseãååšããªãå Žåã®æåãæé©åããããã«ãããã仿§ã«ãªã£ãŠããã®ã§ã¯ãªãããšæããŸãããããã«ãããSuspenseãã©ãã«çœ®ãã®ããšããã®ã¯ã©ã®ã³ã³ããŒãã³ãã®ãµã¹ãã³ããã©ãã§å¯Ÿå¿ããã®ããšããããšã«ãé¢ãããããããããã®Reactã䜿ãããªãã«ããã£ãŠéèŠãªèŠç¹ãšãªããŸãã
以äžãstartTransitionã®æåã§ããã
isPendingã®äœ¿çš
ããŠãuseTransitionããã¯ã¯ããã²ãšã€isPendingãšããå€ãè¿ããŠããŸããæ¬¡ã¯ããã解説ããŸãã
isPendingã¯çåœå€ã§ããæ¬¡ã®ç»é¢ã®ã¬ã³ããªã³ã°ããµã¹ãã³ãããã®ã§ãããåŸ
æ©ããŠããããšããç¶æ³ã«ãããŠtrueãšãªããŸãã
ããŸãã¡äœãèšã£ãŠããã®ãåãããªããšæãã®ã§äŸãçšæããŸãããå
ã»ã©ãšã®éãã¯äžç®æã ãã§ããã¿ã³ã«disabled={isPending}ãšãã屿§ã远å ããŸããã
export const Example03 = () => {
const [showChild, setShowChild] = useState(false);
// ããã§useTransitionã䜿çš
const [startTransition, isPending] = useTransition({
timeoutMs: 10000 // ã¿ã€ã ã¢ãŠãã10ç§ã«èšå®
});
return (
<>
<h1>03 Example of useTransition 2</h1>
<Suspense fallback={<p>loading...</p>}>
{showChild ? (
<AdditionalContents />
) : (
<button
// â ãã®è¡ã远å ãã
disabled={isPending}
onClick={() => {
startTransition(() => {
setShowChild(true);
});
}}
>
远å ã³ã³ãã³ãã衚瀺
</button>
)}
</Suspense>
</>
);
};
ãã®äŸã¯ãã远å ã³ã³ãã³ãã衚瀺ããã¿ã³ãæŒããšå³åº§ã«ãã®ãã¿ã³ãç¡å¹åïŒdisabledïŒãããŠããäžåºŠæŒããªããªããŸããä»ã®ç¹ã¯å
ã»ã©ãšåãã§ã2ç§åŸã«ãã¿ã³ãæ¶ããŠAdditionalContentsã®äžèº«ã衚瀺ãããŸãã
ä»åã¯disabledã ãã§ãããisPendingã¯çµæ§äŸ¿å©ã§ããäŸãã°ã次ã®ç»é¢ã®ã¬ã³ããªã³ã°ããµã¹ãã³ãããŠããéãåã®ç»é¢ã«ããæãã®ããŒãã£ã³ã°è¡šç€ºãåºãããšãã§ããã§ãããã
useTransitionã«ããåæã¬ã³ããªã³ã°
ããã§äœãèµ·ãã£ãŠããã®ããå³ã§è¡šããŠã¿ãŸãããäžã®äŸã«ã¯ãäžã®å³ã§ããA, B, Cãšãã3ã€ã®ç¶æ
ãååšããŸããAã¯showChildãšisPendingãäž¡æ¹ãšãfalseã®ç¶æ
ã§ãBã¯isPendingãtrueã«ã£ãç¶æ
ãCã¯showChildãtrueã«ãªã£ãç¶æ
ã§ãã
åæç¶æ ã¯Aã§ããããã®ã³ã³ããŒãã³ããã¬ã³ããªã³ã°ãããšDOMã«ã¯Aã®ç¶æ ã衚瀺ãããŸãã
ãŠãŒã¶ãŒããã¿ã³ãæŒããšstartTransitionå
ã§ã¹ããŒãã®æŽæ°ãè¡ãããŸããã€ãŸããããã°ã©ã ã«ãã£ãŠCãžã®ç¶æ
é·ç§»ãæç€ºãããããšã«ãªããŸãã
ãšããããuseTransitionã®åãã«ããããŸãBãã¬ã³ããªã³ã°ãããŸãããã€ã³ãã¯ãCãããå
ã«Bãã¬ã³ããªã³ã°ããããšããç¹ã§ããããã¯ããªãã¹ãæ©ããŠãŒã¶ãŒã«ãã£ãŒãããã¯ãè¿ããããšããçç±ããããŸãã
ã€ãŸããäžè¬ã«Cãšããã®ã¯å
šãæ°ããç¶æ
ã§ããèªã¿èŸŒã¿å®äºãŸã§æéãããããããããªãäžæ¹ã§ãBãšããã®ã¯æ®éã¯Aã«å¯ŸããŠãŠãŒã¶ãŒãžã®ãã£ãŒãããã¯ãå ããç¶æ
ã§ãïŒäžã®äŸã ãšãã¿ã³ãdisabledã«ãªããšãããã£ãŒãããã¯ããããŸããïŒãUXçãªèгç¹ãããã£ãŒãããã¯ã¯éãã»ããæãŸãããããBãå
ã«ã¬ã³ããªã³ã°ãããããšã«ãªããŸãã
ãã£ãŠããã¿ã³ãæŒããšãŸãBãã¬ã³ããªã³ã°ãããŠDOMã«åæ ãããŸãããã®åŸã§Cã®ã¬ã³ããªã³ã°ãè¡ãããŸããCã®ã¬ã³ããªã³ã°ããµã¹ãã³ãããªããã°ãCã®ã¬ã³ããªã³ã°çµæãDOMã«åæ ãããŸããCããµã¹ãã³ãããå ŽåãDOMã¯Bã®ç¶æ ãç¶æããŸãã
Cããµã¹ãã³ãããªãã£ãå Žåã¯BãDOMã«åæ âCãDOMã«åæ ãšããæäœãé£ç¶ããŠèµ·ããã®ã§Bã®ã¬ã³ããªã³ã°ãç¡é§ã«ãªã£ãŠããŸããŸããããµã¹ãã³ãããå Žåã®UXãåªå ããŠãã®æåã«ãªã£ãŠãããšæãããŸãã
åæã¬ã³ããªã³ã°ãšããå²ã«ã¯BâCãšçŽåã«ã¬ã³ããªã³ã°ãè¡ãããŠããããã«èŠããŸãããReactã¯å éšçã«BãšCãšãã2ã€ã®ç¶æ ãåæã«ç®¡çããŠããã®ã§ããããã®æå³ã§ã¯åæã¬ã³ããªã³ã°ãšèšããªãããããŸããã
ãŸããBã®ç¶æ ããããã«ã¹ããŒãã®æŽæ°ïŒæŽæ°åŸãB'ãšããŸãããïŒãåŒãèµ·ãããšããæå°æªãå¯èœã§ãããã®å ŽåãCã®ã¬ã³ããªã³ã°ããµã¹ãã³ãããŠããç¶æ ã§B'ã®ã¬ã³ããªã³ã°ãè¡ãããããšã«ãªããåæã¬ã³ããªã³ã°æãå¢ããŸããããã«ããã®æŽæ°ã¯CåŽã«ãåæ ãããŠC'ãäœãããŸãããã®ãšãã®æåã¯cherry-pickã®ãããªæãã§ãã
useTransitionã®æçŸ©
ãããŸã§èª¬æããããã«ãuseTransitionã¯Suspenseãšçµã¿åãããããšã«ãããç»é¢ã®æŽæ°æã«ã¬ã³ããªã³ã°ããµã¹ãã³ãããå Žåã§ã®ãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãåäžãããããšãã§ããŸãã
ãã ã䌌ããããªæåã¯åŸæ¥ããããã¹ããŒã管çã®ææ³ã§ãåçŸã§ããã§ãããããã¿ã³ãæŒããæ®µéã§isPendingãšããã¹ããŒããtrueã«ããŠãããŒããå®äºããæ®µéã§showChildãtrueã«ãããããªããžãã¯ãæžãã°ããã®ã§ãã
åŸæ¥ã®ææ³ã®åé¡ã¯ããã®ãããªããžãã¯ã¯äžå€®éæš©çã«ãªããã¡ãšããç¹ã§ããè€æ°ã®ç»é¢ã«ãŸãããããžãã¯ã§ãã以äžãããžãã¯ãåã ã®ã³ã³ããŒãã³ãå ã«ããŸã蟌ãã§ããŸãããšã¯é£ãããããã¯ä»æ¹ããããŸãããéã«èšãã°ãã ããããããã®åé¡ãReactæ¬äœã®è¿œå æ©èœãšããŠæäŸãã䟡å€ããããšãèšããŸãã
å®éãuseTransitionïŒãããŠSuspenseïŒã®æçŸ©ã¯ã³ã³ããŒãã³ãéã®ããžãã¯ã®åé¢ã«ããããã«æããŸããSuspenseã䜿ãå Žåããã©ããªããŒã¿ãããŒããããããšããããŒã¿ã®èªã¿èŸŒã¿å®äºããã€ãããšãã£ãããžãã¯ã¯ãã®ããŒã¿ã䜿ãã³ã³ããŒãã³ãïŒäžã®äŸã§ã¯AdditionalContentsïŒã«å
å
ãããŸãããŸãããã£ãŒãããã¯ã衚瀺ããåŽïŒisPendingã䜿ãåŽïŒããäœãã©ããµã¹ãã³ãããŠããã®ãã¯æ°ã«ããå¿
èŠããããŸããã
å®éã¯âäžå€®âãReactã®å éšã«ç§»åããã ããããããŸãããããã®æ¹ãReactãâããŸãããâããšãã§ãããšå€æããããããããã®æ©èœãããã®ã§ããããå°æ¥çã«ã¯ããã©ãŒãã³ã¹äžã®æ©æµãªã©ããããããããŸãããä»è§Šã£ãŠã¿ãéãã§ã¯ãïŒUXã§ã¯ãªãåçŽãªåŠçé床ã®èгç¹ããã¯ïŒçŽæ¥ããã©ãŒãã³ã¹ã®åäžã«ç¹ãã£ãŠããæãã¯ããŸããã§ãããã
ãŸããããããäžå€®éæš©çãªã¹ããŒã管çãè¯ãã®ãæªãã®ãããšããã®ãçãã®ããåé¡ã§ã¯ãããŸãããuseTransitionã¯Reactã瀺ããã²ãšã€ã®çãã§ããããããã£ãé åã«æãåºããŠããã®ã¯å°ãã©ã€ãã©ãªãšããŠã®åã¿ãå¢ããŠãããªãšããææ³ãæãããããŸãã
useDeferredValue
ããã²ãšã€ã®ããã¯ã¯useDeferredValueã§ãããã¡ãã¯å®ã¯SuspenseãšçŽæ¥é¢ä¿ãããããã§ã¯ãªãã®ã§ãããReactãConcurrent Modeãå®è£
ããããšã«ããå¯èœã«ãªã£ãæ©èœã§ãã
æåã®äŸ
ããšããšã§èšããšãuseDeferredValueã¯å€ã®æŽæ°ãããæãã«é
ãããŠãããããã¯ã§ããäŸãèŠãŸãããã
export const Example04 = () => {
const [text, setText] = useState("");
const deferredText = useDeferredValue(text, { timeoutMs: 10000 });
console.log(text, deferredText);
return (
<>
<h1>04 Example of useDeferredValue</h1>
<p>
<input value={text} onChange={e => setText(e.currentTarget.value)} />
</p>
<p>{deferredText}</p>
</>
);
};
ããã¯ãuseStateã§å®£èšããtextãšããã¹ããŒããinputèŠçŽ ãéããŠå€æŽã§ãããšããããæ®éã®UIã§ãã
4è¡ç®ã§useDeferredValueã«textãæž¡ããŠãè¿ãå€ãšããŠdeferredTextãåŸãŠããŸããããã«ãã®deferredTextãã¬ã³ããªã³ã°ããŠããŸãã
å®éã«ãã£ãŠã¿ããšãinputã«å
¥åããå
容ãäžã«å³åº§ã«åæ ãããããã«èŠããŸããã€ãŸããäžèŠãããšdeferredTextã¯textãšåãã«ãªã£ãŠããããã«èŠããŸããããããå®éã«èµ·ãã£ãŠããããšã¯å°ãç°ãªããŸããããããããã解説ããŠãããŸãã
useDeferredValueã®æ©èœ
æåã«è¿°ã¹ãããã«ãuseDeferredValueã¯åŒæ°ã«æž¡ããå€ãããæãã«é
å»¶ããŠè¿ããŠãããããã¯ã§ãããšèšããŸãã
ãã®æåã¯textãå€ãã£ãç¬éã«å¹æãçºæ®ããŸããtextãå€ãããšåœç¶åã¬ã³ããªã³ã°ãçºçããŸãããdeferredTextã«ã¯å€ããåã®textãå
¥ããŸããã
ãã®åŸããæãã®ã¿ã€ãã³ã°ã§ããäžåºŠåã¬ã³ããªã³ã°ãçºçãããã®édeferredTextã«å
¥ãã®ã¯çŸåšã®textãšãªããŸãã
ããæãã®ã¿ã€ãã³ã°ãšããã®ã¯çµå±äœããšãããšãReactã®ã¹ã±ãžã¥ãŒãªã³ã°ã«ä»»ããããšã«ãªããŸããReactãå¿ãããªããšãã¯äžç¬ã§åæ ãããŸãããä»ã®äœæ¥ã§å¿ãããšãã¯çµæ§åæ ãé å»¶ãããããšã«ãªããŸããé å»¶ã®æå€§å€ãå®ãããå Žåã¯
ã€ãŸããuseDeferredValueã®äœ¿ãéã¯äžéšã®ã³ã³ããŒãã³ãã®ã¬ã³ããªã³ã°ãããæãã«é
å»¶ãããšããå Žåã«ããããšã«ãªããŸãã
å®éãäžã®äŸã§ã¯console.logã§textãšdeferredTextã䞊ã¹ãŠè¡šç€ºããŠãããããããã確ãããŠã¿ãŸããããå
¥åæ¬ã«ãabcdeããšå
¥åãããšä»¥äžã®ãããªãã°ã䞊ã³ãŸããå·Šãtextã§å³ãdeferredTextã§ãã
a
a
a a
a a
a a
a a
ab a
ab a
ab ab
ab ab
ab ab
ab ab
abc ab
abc ab
abc abc
abc abc
abc abc
abc abc
abcd abc
abcd abc
abcd abcd
abcd abcd
abcd abcd
abcd abcd
abcde abcd
abcde abcd
abcde abcde
abcde abcde
abcde abcde
abcde abcde
åãç¶æ
ãäœåãã¬ã³ããªã³ã°ãããŠããã®ã¯ïŒå€åstrict modeã¿ãããªãã®ãªã®ã§ïŒæ°ã«ããªãããšã«ããŠãããèŠããštextãæŽæ°ãããã¿ã€ãã³ã°ãšdeferredTextãæŽæ°ãããã¿ã€ãã³ã°ãç°ãªã£ãŠããŸããäŸãã°ab aãšãããã°ã¯ãtextãæŽæ°ãããŠ'ab'ã«ãªã£ããdeferredTextã¯ãŸã åã®ç¶æ
ã§ãã'a'ã§ããç¶æ
ããã£ãããšã衚ããŠããŸããå®éã¯ãã®çŽåŸã«deferredTextãæŽæ°ãããŠ'ab'ã«ãªããããab abãšãããã°ãåºãããšã«ãªããŸãã
ãã®ããã«ãäžã®äŸã§ãå®éã«ãŸãtextãæŽæ°ãããŠããããããé
ããŠdeferredTextãæŽæ°ãããŠããããšãèŠãŠåããŸãããã ãäžç¬ã ã£ãã®ã§ç®ã§èŠãŠãåãããŸããã§ããã
useDeferredã«ããé
å»¶ã芳å¯ãã
ã§ã¯ã次ã®äŸã§ã¯å®éã«é å»¶ã芳å¯ããŠã¿ãŸãããããã®ããã«ã¯ãReactã«éãä»äºããããã°ããããšã«ãªããŸãããšããããã¬ã³ããªã³ã°éãå¢ãããŠã¿ãŸãã
export const Example05 = () => {
const [text, setText] = useState("");
const deferredText = useDeferredValue(text, { timeoutMs: 10000 });
console.log(text, deferredText);
return (
<>
<h1>05 Example of useDeferredValue 2</h1>
<p>
<input value={text} onChange={e => setText(e.currentTarget.value)} />
</p>
<Show10000Times text={deferredText} />
</>
);
};
const Show10000Times: React.FC<{
text: string;
}> = memo(({ text }) => (
<p>
{Array.from({ length: 100 }).map((_, i) => (
<Show100Times text={text} />
))}
</p>
));
const Show100Times: React.FC<{
text: string;
}> = ({ text }) => (
<>
{Array.from({ length: 100 }).map((_, i) => (
<span key={i}>{text}</span>
))}
</>
);
æ°ãã«è¿œå ãããShow10000Timesãšããã³ã³ããŒãã³ãã¯ãæž¡ãããtextãäžäžåæç»ããã³ã³ããŒãã³ãã§ãããã®äžèº«ã¯Show100Timesã100åãšããæ§æã§ããå®ã¯ããã¯åã«äžäžåã«ãŒãããŠspanã䞊ã¹ããããReactã«éœåãè¯ãèšå®ã«ãªã£ãŠããŸãïŒã¬ã³ããªã³ã°åŠçãåå²ããããããïŒã
å
ã»ã©ã®äŸãšåæ§ã«inputèŠçŽ ã«ããã¹ããå
¥åããŠã¿ããšãäžã«ãããé·ãæååãåºçŸããŸãã1äžåã®spanèŠçŽ ãã¬ã³ããªã³ã°ããªããã°ãªããªãé¢ä¿ã§ã©ãããŠãéããªããŸããã
ä»åãconsole.logãããã®ã§èгå¯ããŠã¿ãŸãããããããšãå
ã»ã©ãšã¯éã£ãŠdeferredTextã¯textãããã ãã¶é
ããŠä»ããŠããããšãåãããŸããReactãã¬ã³ããªã³ã°ã§å¿ããããdeferredTextã®æŽæ°ãé£ã°ãããã®ã§ãã
useDeferredValueã®æçŸ©
useDeferredValueã§å€ã®å€åã®é
å»¶ã衚çŸã§ããããšãåãããŸãããå€åã®é
å»¶ã¯ããæãã«ãããšãæãã§ãããå€ãå€åãããšããæãã®æåã«ãªããŸãïŒæ£ç¢ºãªæåã調ã¹ãããã§ã¯ãªãã®ã§ãããŸãããïŒã
ã§ã¯ãããã¯äœã®åœ¹ã«ç«ã€ã®ã§ããããããã®çãã¯ããç»é¢ã®æŽæ°ã®äžéšãé
å»¶ããããšããã§ããç»é¢ãæŽæ°ãããšãã«æåªå
ã§è¡šç€ºãããæ
å ±ãšããã§ããªãæ
å ±ããããããªå Žåã«useDeferredValueã䜿çšã§ããå¯èœæ§ããããŸãã
æåªå
ã§è¡šç€ºãããæ
å ±ãšããã®ã¯ã代衚çãªãã®ã¯ãŠãŒã¶ãŒãžã®ãã£ãŒãããã¯ã§ããããã¯useTransitionã®ãšããåºãŠããããŒã¯ãŒãã§ãããç¹ã«äžã®ãµã³ãã«ã®inputèŠçŽ ã®å Žåãããã¯controlled componentã§ããããtextãšããã¹ããŒãã®å€æŽãããã«åæ ãããªããšãŠãŒã¶ãŒãéåæãæããŠããŸããããäœãå·®ã眮ããŠãæåªå
ã§åã¬ã³ããªã³ã°ãå®éããå¿
èŠããããŸãã
äžæ¹ã§ãäžã®<Show10000Times text={deferredText} />ã¯ãããããåªå
床ãäœãæ
å ±ã§ãããinputèŠçŽ ãšåã¬ãã«ã®è»œå¿«ãã¯æ±ããããŸããããã®ããããã§textã§ã¯ãªãdeferredTextãæž¡ããŠããŸããããã«ãããtextãæŽæ°ãããç¬éã«Show10000Timesãåã¬ã³ããªã³ã°ããå¿
èŠãç¡ããªãã®ã§ãã
å®éã«ãµã³ãã«ãåãããŠããæ¹ã¯ã詊ãã«ããã<Show10000Times text={text} />ã«å€ããŠã¿ãŸãããããããšãinputèŠçŽ ã®å¿çæ§ãããªãæªããªãã¯ãã§ããããã¯textãå€ãããã³ã«ãã®ã³ã³ããŒãã³ããåã¬ã³ããªã³ã°ããå¿
èŠãããããããçµãããªããšinputèŠçŽ ãåã¬ã³ããªã³ã°ãããªãããã§ãã
ãŸãšãããšããã®äŸã§ã¯useDeferredTextãçšããŠShow10000Timesã®åã¬ã³ããªã³ã°ãé
å»¶ãããããšã§ãinputèŠçŽ ã®åå¿é床ãæããŠããã®ã§ãã
useTransitionã®ãšããšåæ§ã«ããã®åé¡ãé©åãªã¹ããŒã管çã«ãã£ãŠã解決ã§ãããããããŸããããããã«ãé¢ãããReactããã®æ©èœãçšæããçç±ã¯ããã¯ãã¬ã³ããªã³ã°ã®äžçªé©åãªã¹ã±ãžã¥ãŒãªã³ã°ãåºæ¥ãã®ã¯Reactèªèº«ã ãããšããããšã«å°œããã§ãããã
useDeferredValueãåŸæãªç¶æ³ãšèŠæãªç¶æ³
å®ã¯ãäžã®äŸã¯ãµã³ãã«ãšããŠæåã®ãã®ã§ã¯ãããŸãããå®éãinputèŠçŽ ãããã£ãŠãããšããããé »ç¹ã«ïŒShow10000Timesã®åã¬ã³ããªã³ã°ãèµ°ããã³ã«ïŒå¿çæ§ãæªããªã£ãŠããŸããŸãã
ããã¯ãïŒãŸã£ãã广ãç¡ãããã§ã¯ãããŸãããïŒä»åã®ãµã³ãã«ãuseDeferredValueã®èŠæãªç¶æ³ã ããã§ãã
å
·äœçã«ã¯ãä»åå¿çæ§ãæªããªãåå ã¯show10000Timesã®ã¬ã³ããªã³ã°ã®ããã«ããã¯ãDOMãžã®åæ ã ããã§ãããŠãŒã¶ãŒã«äžéå端ãªç¶æ
ãèŠããªãããã«ãããããä»®æ³DOMãå®éã®DOMãžãšåæ ãããäœæ¥ã¯äžæ°ã«è¡ãå¿
èŠããããŸãããã®ããããã£ããReactãã¬ã³ããªã³ã°ãäžæã§ããæ©èœãå®è£
ãããšãã£ãŠããDOMãžã®åæ ã¯åå²ã§ããªãã®ã§ãããŸããã ããããå®éã®DOMæäœãæå°éã«ããããšãéèŠã«ãªã£ãŠããã®ã§ããã
éã«èšãã°ãä»®æ³DOMã®æ§ç¯æ®µéãéãå ŽåïŒåçŽã«ããªãŒã倧ãããšãã颿°ã³ã³ããŒãã³ãã«éãåŠçããããªã©ïŒã®å Žåã¯useDeferredValueã®åŸæãªç¶æ³ãšãªããŸããä»®æ³DOMã¬ãã«ã®ã¬ã³ããªã³ã°ã®æ®µéã§ã¯Reactãããäžæã«ã¹ã±ãžã¥ãŒãªã³ã°ãè¡ãããšãã§ããããã§ã1ã
useDeferredValueãšuseTransitionã®äœµçš
ãããŸã§ã§2ã€ã®ããã¯ã玹ä»ããŸããã®ã§ãæåŸã«2ã€ã䜵çšããäŸã玹ä»ããŸãã
ç¹ã«ãäžã®useDeferredValueã®äŸã¯ã¡ã€ã³ã¹ã¬ãããå°æããã¬ã³ããªã³ã°åŠçã«å¯Ÿãã察å¿çã§ããããå®ã¯useDeferredValueã¯Suspenseãšçµã¿åãããŠãããæãã«åããŸãã
ä»åã®äŸã¯ããã§ãã
export const Example06 = () => {
const [text, setText] = useState("");
const [dataId, setDataId] = useState(0);
const [startTransition] = useTransition({ timeoutMs: 10000 });
const deferredDataId = useDeferredValue(dataId, { timeoutMs: 10000 });
return (
<>
<h1>06 Example of useDeferredValue 3</h1>
<p>
<input
value={text}
onChange={e => {
const newText = e.currentTarget.value;
setText(newText);
startTransition(() => {
setDataId(newText.length);
});
}}
/>
</p>
<Suspense fallback={<p>Loading...</p>}>
<p>ããŒã¿ID: {dataId}</p>
<LoadedContents dataId={deferredDataId} />
</Suspense>
</>
);
};
const LoadedContents: React.FC<{ dataId: number }> = ({ dataId }) => {
const data = getData(dataId);
return <p>{data}</p>;
};
ãŸãSuspenseã®è©±ãªã®ã§ãããŒã¿ãããŒãããŠè¡šç€ºããã³ã³ããŒãã³ãLoadedContentsãçšæããŸãããããŒã¿ãèªã¿èŸŒãã«ã¯æéããããããããã®ã³ã³ããŒãã³ãã¯ãµã¹ãã³ãããå¯èœæ§ããããŸãã
å®éã®åäœãšããŠã¯ãinputèŠçŽ ã«å
¥åããæååã®æåæ°ãããŒã¿IDãšããŠè¡šç€ºãããããã«äžå®æéåŸã«ãã®IDã®ããŒã¿ãèªã¿ããŸããŠè¡šç€ºãããŸããuseDeferredValueã®å¹æã«ãããããŒã¿IDãšå®éã«è¡šç€ºãããããŒã¿ã«å·®ç°ãçºçããããšããããŸããäžã®äŸã§ã¯ãããŒã¿IDã21ãªã®ã«å®éã«è¡šç€ºãããŠããããŒã¿ã¯17çªã®ãã®ã§ãã
useDeferredValueãšuseTransitionã®äœµçšæã®æå
äžèº«ã®è§£èª¬ã«ç§»ããŸããã¡ã€ã³ã®ã³ã³ããŒãã³ãïŒExample06ïŒã®ã¹ããŒãã¯äºã€ã§ãã²ãšã€ã¯useDeferredValueã®äŸãšåããtextãããã²ãšã€ã¯dataIdã§ããdataIdã¯èªã¿èŸŒã¿ããããŒã¿ã®çªå·ã§ããdataIdã¯textã®æåæ°ãšããŸãã
ãããªãããããdataIdãšããã¹ããŒããçšæããªããŠãconst dataId = text.length;ã§ãããããªæ°ãããªãã§ããªãã§ãããä»åããã§ããªãçç±ããããŸããinputèŠçŽ ã®onChange屿§ãèŠããšåãããŸãããtextã¯startTransitionã®å€ã§ãdataIdã¯äžã§å€æŽããŠããŸãããã®éãã®ããã«ã¹ããŒããå¥ã
ã«ããå¿
èŠããã£ãã®ã§ãã
startTransitionã®å€ã§å€æŽãããŠããtextã¯å³åº§ã«å€æŽãããŸããããã«ãããinputèŠçŽ ã¯åžžã«ãŠãŒã¶ãŒã®å
¥åã«å¯Ÿãããã£ãŒãããã¯ãçŽ æ©ãè¿ããŸãã
dataIdã¯<p>ããŒã¿ID: {dataId}</p>ãšãããšããã§äœ¿ãããŠããŸããããã¯startTransitionã®äžã§å€æŽããããããæ°ããããŒã¿ãèªã¿ããŸãããŸã§ã¯è¡šç€ºãæŽæ°ãããŸããâŠâŠãšãããããšããã§ãããå®ã¯ããã§ããããŸãããäžèšã®ããã«ãæ°ããããŒã¿ãèªã¿ããŸããåã«dataIdãæŽæ°ãããããšããããŸãã
ããã¯useDeferredValueã«ãããã®ã§ããLoadedContentsã«æž¡ããŠããã®ã¯deferredDataIdã§ãããdataIdãæŽæ°ãããçŽåŸã¯ãŸã deferredDataIdãæŽæ°ãããŠããªãããã«ãµã¹ãã³ããçºçããŸãããããã«ãããå³åº§ã«dataIdã®æŽæ°ãç»é¢ã«åæ ãããã®ã§ãããã ãuseTransitionã®å¹æã«ãããäžæŠãµã¹ãã³ããçºçãããdataIdã®æŽæ°ãç»é¢ã«åæ ãããªããªããŸããããã«ãããdataIdãåžžã«ãŽã£ããtextã«è¿œéãããšããããã§ããªããªããŸãã
ããã§åŒ·èª¿ãããã®ã¯useDeferredValueã®å¹æã§ãããµã¹ãã³ãããã³ã³ããŒãã³ãã«æž¡ãããå€ãé
å»¶ãããããšã§å€æŽçŽåŸã®ãµã¹ãã³ããé²ãããšãã§ããå¯èœæ§ãããããã®çµæãšããŠdataIdã®å€åãæ©ãã«ãŠãŒã¶ãŒã«è¡šç€ºãããã®ã§ãã
ä»åã¯ããŸãæå³ããªãäŸã«èŠããŸãããè€æ°ã®ãœãŒã¹ããããŒã¿ãèªã¿èŸŒããšãã«æ©ãã»ãã®ããŒã¿ãèªã¿èŸŒãããããã«è¡šç€ºãããã€é ãããŒã¿ã¯èªã¿èŸŒã次第衚瀺ããïŒãããŸã§ã¯å€ãããŒã¿ã衚瀺ããŠããïŒãšãããããªå Žåã«ãããŠåœ¹ã«ç«ã¡ããã§ãã
useDeferredValueãšSuspense
ä»åã®äŸã§ããuseDeferredValueã«ããããããã®é
å»¶ãçºçããŠããããšãåãããŸããã
ããããä»åã¯åã®äŸã®ããã«ã¡ã€ã³ã¹ã¬ããçã«éãåŠçãããããã§ã¯ãããŸããã代ããã«ããã®ã¯ãµã¹ãã³ãããã³ã³ããŒãã³ãã§ãã
ãã®ããšããããµã¹ãã³ãããã³ã³ããŒãã³ããuseDeferredValueã«å¯Ÿããã¹ã±ãžã¥ãŒãªã³ã°ã«åœ±é¿ãäžããããšãåãããŸãã
æ£çŽã«è¿°ã¹ããšãã©ããªæã«ã©ããããé å»¶ããã®ãã¯ããåãããŸããã§ãããäŸãã°å ¬åŒã®ãµã³ãã«ã§ã¯ãµã¹ãã³ãããŠããã³ã³ããŒãã³ããäžã€ã¬ã³ããªã³ã°å®äºããæç¹ã§é å»¶æŽæ°ãè¡ãããæåã確èªã§ããŸããããªããã®ã¿ã€ãã³ã°ãªã®ãã¯éèªæã§ããæãããReactåŽãšããŠãããã¯ãã¥ãŒãªã¹ãã£ã¯ã¹ã®å ¥ãäœå°ãããéšåãªã®ã§ãããŸãå³ããå¶çŽããããããªãã®ã§ããããšæããŸãã
ä»ã®ãšããå¯äžä¿¡é Œã§ããæ§è³ªã¯ãå
ã®å€ãå€åããç¬éã¯useDeferredValueã®è¿ãå€ã¯ããã«è¿œéããªããšãããã®ã ãšæãããŸããã€ãŸããå¿
ãå
ã®å€ïŒuseDeferredValueã®åŒæ°ã«æž¡ãããå€ïŒãããå€ãå€ãè¿ãããç¬éãååšããããã§ãã
å人çã«ã¯ãæ£åŒçãªãªãŒã¹ãŸã§ã«ã¯ããå°ãåããããããªã£ãŠã»ãããªããšæããªãã§ããããŸããã䜿ãç¶ããŠããã°ãã®ãã¡çè§£ã§ãããããããŸããã®ã§ã次ã®èšäºãæåŸ ããã«ãåŸ ã¡ãã ããã
ææ
ãŸãæåã«Promiseãthrowããããšã«ã€ããŠè¿°ã¹ãŠãããšããªããªãé¢çœãã§ãããéåæåŠçãšããã®ã¯ã©ããäžç®æã§ãæ··ãããããšåŠçã®å
šäœãéåæã«å¯Ÿå¿ããããã«æžããªããšãããªãããã§ããããã®å¯Ÿå¿ãReactã«äžžæãïŒæåéãïŒããããšã§åŒ·åŒã«è§£æ±ºãããŠãŒã¶ãŒã©ã³ãã§ã¯ãŸãã§åæåŠçã®ããã«èŠããåŠçãæžãããšãã§ããŸãïŒé¢æ°åèšèªã®ãŠãŒã¶ãŒãã¡ã¯å¯äœçšã®çš®é¡ãå€ãã£ãã ãããããšèšããããããŸãããïŒããããâè¯ãâãã©ããã¯ããŠãããReactçãªçºæ³ã§ãããšæããããŸããã
ããŠããã®èšäºã§ã¯2ã€ã®æ°ããããã¯ã玹ä»ããŸããããäž¡æ¹ã«å ±éããããŒã¯ãŒãã¯ãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã§ããããç¹ã«ãæãŸãããã£ãŒãããã¯ãæéã§è¿ãããšã«çŠç¹ã眮ãããŠããŸãããã¡ããããã¯åŸæ¥ããæã ãå¿è¡ã泚ãã§ãããã®ã§ãããä»åReactæ¬äœã«ãããæ¯æŽããæ©èœãå ¥ã£ãããšã«ãªããŸãã
ãã®èæ¯ã¯ãäžã€ã¯Reactæ¬äœãããã¹ãä»äºãReactæ¬äœãããããã«ãããšããåçŽãªè©±ã§ãããããããäžã€ãäžå€®éæš©çã§ã¯ãªãã³ã³ããŒãã³ãããŒã¹ãªææ³ãããã«æšé²ããŠããææãæããããŸãã
å人çãªææãšããŠã¯ã確ãã«ãã®æ¹åæ§ã§åºæ¥ãããšãåºãã£ããã®ã®ããŸã å šéšææ¡ããããæ°ãããªããªããšæããŠããŸããè²ã ãªã³ã³ããŒãã³ããã¹ããŒããæã£ãŠããã ãã§ã倧å€ãªã®ã«ãããããµã¹ãã³ããããããªãã£ãããããšãªããšãããžãã¯ã®å šäœåã®ææ¡ã¯éåžžã«å°é£ã«ãªããŸãã
Reactã®ææ³ãšããŠã¯ãã³ã³ããŒãã³ããæãæšæ§é ãäžå¿ã«æ®ãããšããç¹ã§ã¯ãšãŠãäžè²«ããŠããŸããæšæ§é ã®äžã§ããžãã¯ãé©åã«åå²ããŠããããšã§æã ãèããªããã°ãããªãããšãæžãããšããæ¹åæ§ãèŠãŠåããŸãã
ããããèšããããšã¯ãSuspenseãå§ããšãããããã®æ°æ©èœã䜿ãããªãã«ã¯ãã®ããã®ç²Ÿå·§ãªèšèšãå¿
èŠã§ããããšããããšã§ããåŸæ¥äžå€®éæš©çãªæ¹æ³ã§è§£æ±ºãããŠããåé¡ã«å¯ŸããŠReactã¯ã³ã³ããŒãã³ãããŒã¹ã®æ°ããªã¢ãããŒããäžããŸãããæ¬¡ã«æã
ããã¹ãããšã¯ãã®ã¢ãããŒããåãå
¥ãååŒããããšã§ãã
ReactèªäœããSuspenseãšã³ã·ã¹ãã ããšåŒãã§ããããã«ãPromiseãthrowãããšãã£ãæŠå¿µã¯ãåšèŸºã©ã€ãã©ãªã«æ°ããªåœ±é¿ãäžããŸããããã¯ã¡ããã©Hooksãç»å Žãããšãã®ããã§ãã
Reactã¯data fetching libraryãäž»ã«èŠãŠããããã§ããããã®æµãã§ç¶æ 管çã©ã€ãã©ãªã«ãæ°ããèšèšã®ãã®ãåºãã®ã§ã¯ãªãããšæããŸãããã®èšäºãèªãã§concurrent modeãå®å šã«çè§£ãããšããæ¹ãããã°èªåã§äœã£ãŠã¿ãŠããããããããŸããã
ãŸããä»åã®æ°æ©èœã«ãã£ãŠReactã®éèªæããå¢ãããšããå°è±¡ãåããŸãããç¹ã«useDeferredValueã®æåã«ãããŠé¡èã§ããããã«ãuseTransitionã絡ãã§ãããšäœããã€åã¬ã³ããªã³ã°ãããã®ãæ£çŽãŸã äºæž¬ãä»ããŸããã䜿ã£ãŠãããã¡ã«çè§£ã§ããã®ãããããšãçè§£ããããšããªããšãã£ãšéèªæãªãŸãŸãªã®ãã¯ãŸã å®ãã§ã¯ãããŸããã
å ã«ãè¿°ã¹ãããã«Reactã¯çµæã®æŽåæ§ãä¿ã¡ã€ã€ã¬ã³ããªã³ã°äžã®çš®ã ã®ä¿èšŒãæžããæ¹åã«åããŠããŸããèªåã¯ãããŸã§Reactã¯ãã¬ãŒã ã¯ãŒã¯ãããªããŠã©ã€ãã©ãªã ããšãã䞻匵ãç¶ããŠããŸããããäœãšãªããã¬ãŒã ã¯ãŒã¯ã£ãœããåºãŠãããªããšããæ°ãããªãã§ããããŸããã
ãŸãšã
ãŸããèšäºã®åŸåã«ãªãã«ã€ããŠæç« ãèªã¿ã«ãããªã£ãŠãã£ããšæããŸããæåã¯çé¢ç®ã«èšäºãæžããŠããã®ã§ããåŸåç²ããŠããŠãã ãã ãReactãè§Šã£ãŠè³å ããã³ãããã ãã¿ãããªæç« ã«ãªã£ãŠããŸããŸãããããã§ãäœãã®åèã«ãªãã°å¹žãã§ãã
ãšããããšã§ã10æ25æ¥ã«å
¬éãããReact Concurrent Modeã®ãã¬ãã¥ãŒçã調æ»ããuseTransitionãšuseDeferredValueãšãã2ã€ã®æ°ããããã¯ã«ã€ããŠãŸãšããŸããã
useTransitionã¯ç»é¢é·ç§»åãšåŸã®2ã€ã®ç¶æ
ãReactã«åæã«ç®¡çããŠãããããšãã§ããããã¯ã§ããããŸããuseDeferredValueã¯å€ãããæãã«é
å»¶ããªããå€åãããšããããã¯ã§ããã
ããããã©ããªåé¡ã解決ããã®ããšèšãã°ããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã®åäžã§ãããã®ããã«ReactãäŸããŠããã¹ãæ©èœãšããŠäžèšã®ããã¯ã远å ãããããã§ãã
ãããå®çŸããã«ã¯äžæå¯èœãªã¬ã³ããªã³ã°ã®æ©æ§ãå¿ èŠã§ããããé·ãæéããããŠå®è£ ãããconcurrent modeã§ãã
ææã¯äžã«è¿°ã¹ãéãã§ããããŸãšãçŽããšReactã®éèªæããå°ãå¢ãããªãšããå°è±¡ãåããŸãããçè ã¯7ã8æéãããã¯Reactã®concurrent modeãããããŸãããããŸã è¯ãããã£ãŠããªãç¹ãå€ããããŸãã
çè§£ãæ·±ããã«ã¯ãã£ãšäœ¿ãåãå¿ èŠããããšæããŠããŸãããReactå ¬åŒåŽããã®ãããªã解説ãã§ããã°æåŸ ããããšããã§ãã
-
ãã ããã²ãšã€ã®é¢æ°ã³ã³ããŒãã³ãã®åŠçã«ãã®ãããæéãããããšãããããªç¶æ³ã«ã¯ç¡åã§ããReactã§ããããã«é¢æ°ã®å®è¡ãäžæãããããšã¯ã§ããªãããã§ããããããããããããã®é¢æ°ã³ã³ããŒãã³ãããã£ãŠå šéšåŠçãããšæããšãããããªç¶æ³ã«å¯ŸããŠããæå¹ã§ãã â©

