Reactã®experimental_useOpaqueIdentifierããã¯ã§ãè€éãªã³ã³ããŒãã³ãããªãŒã§ã®å®å®ããIDçæãæ¢ããŸããå©ç¹ããŠãŒã¹ã±ãŒã¹ããã¹ããã©ã¯ãã£ã¹ã解説ããŸãã
React experimental_useOpaqueIdentifier ã®å®å®æ§ïŒID管çã®æ·±æã
é²åãç¶ããReactéçºã®äžçã«ãããŠãå®å®çã§äºæž¬å¯èœãªã³ã³ããŒãã³ãã®æåãç¶æããããšã¯æãéèŠã§ããå®å®æ§ã®ç¢ºä¿ãé£ããé åã®äžã€ãIDçæã§ãããç¹ã«è€éãªã³ã³ããŒãã³ãéå±€ãåçãªã¬ã³ããªã³ã°ãæ±ãå Žåã«é¡èã§ããReactã® experimental_useOpaqueIdentifier ããã¯ã¯ãã³ã³ããŒãã³ãå
ã§äžæã§å®å®çããã€äžéæãªïŒopaqueïŒèå¥åãçæããã¡ã«ããºã ãæäŸããããšã§ããã®åé¡ã«å¯Ÿãã解決çãæç€ºããŸãã
experimental_useOpaqueIdentifierãšã¯äœãïŒ
experimental_useOpaqueIdentifier ã¯ãã³ã³ããŒãã³ãã€ã³ã¹ã¿ã³ã¹ã®ããã®äžæã§äžéæãªèå¥åãçæããããã«èšèšãããReactããã¯ã§ãããã®æèã«ããããäžéæããšã¯ãèå¥åã®æ£ç¢ºãªå€ã¯éèŠã§ã¯ãªããç¹å®ã®æå³ã圢åŒã«äŸåãã¹ãã§ã¯ãªãããšãæå³ããŸãããã®äž»ãªç®çã¯ãã³ã³ããŒãã³ãã®propsã芪ã³ã³ããŒãã³ãã倿Žãããå Žåã§ããã¬ã³ããªã³ã°ãè¶ããŠæç¶ããå®å®ããèå¥åãæäŸããããšã§ãã
ãã®ããã¯ã¯çŸåšãå®éšçïŒexperimentalïŒãšãããŠããããã®APIãæåã¯å°æ¥ã®ReactãªãªãŒã¹ã§å€æŽãããå¯èœæ§ããããŸããããããããã¯ReactãID管çã®èª²é¡ãç¹ã«ã¢ã¯ã»ã·ããªãã£ããµãŒããŒãµã€ãã¬ã³ããªã³ã°ã«é¢é£ããã·ããªãªã«ã©ã®ããã«åãçµãã§ãããã«ã€ããŠã®è²ŽéãªæŽå¯ãæäŸããŸãã
ãªãå®å®ããID管çãéèŠãªã®ãïŒ
å®å®ããID管çã¯ãããã€ãã®çç±ã§éåžžã«éèŠã§ãïŒ
- ã¢ã¯ã»ã·ããªãã£ïŒARIA屿§ïŒïŒ ã¢ã¯ã»ã·ãã«ãªUIãæ§ç¯ããéãã³ã³ããŒãã³ãã¯ãã°ãã°
aria-labelledbyãaria-describedbyã®ãããªARIA屿§ã䜿çšããŠçžäºã«é¢é£ä»ããå¿ èŠããããŸãããããã®å±æ§ã¯ãUIãæŽæ°ãããŠãèŠçŽ éã®æ£ããé¢ä¿ãç¶æããããã«ãå®å®ããIDã«äŸåããŠããŸããå®å®ããIDããªããã°ãã¢ã¯ã»ã·ããªãã£æ©èœãå£ããéãããæã€äººã ã«ãšã£ãŠã¢ããªã±ãŒã·ã§ã³ã䜿çšäžèœã«ãªãå¯èœæ§ããããŸããäŸãã°ãäžçäžã§æœåšçã«è€éãªæŠå¿µã®çè§£ãå©ããããã«åºã䜿çšãããŠããã«ã¹ã¿ã ããŒã«ãããã³ã³ããŒãã³ãã¯ããã®ã¿ãŒã²ããèŠçŽ ããåç §ãããããã«å®å®ããIDãå¿ èŠãšããŸããã¢ã©ãã¢èªïŒå³ããå·ŠãžïŒãæ¥æ¬èªïŒçžŠæžãïŒã®ãããªèšèªã§ããŒã«ããããã¬ã³ããªã³ã°ããéã®è€éããèãããšãäžè²«ããŠå®å®ããIDã®éèŠæ§ã¯ããã«æçœã«ãªããŸãã - ãµãŒããŒãµã€ãã¬ã³ããªã³ã°ïŒSSRïŒãšãã€ãã¬ãŒã·ã§ã³ïŒ SSRã§ã¯ãã³ã³ããŒãã³ãã¯ãµãŒããŒã§ã¬ã³ããªã³ã°ããããã®åŸã¯ã©ã€ã¢ã³ãã§ãã€ãã¬ãŒã·ã§ã³ãããŸãããµãŒããŒã§çæãããIDãã¯ã©ã€ã¢ã³ãã§çæããããã®ãšç°ãªãå Žåããã€ãã¬ãŒã·ã§ã³ãšã©ãŒãçºçããäºæããªãæåãããã©ãŒãã³ã¹ã®åé¡ã«ã€ãªããå¯èœæ§ããããŸããå®å®ããIDã¯ããµãŒããŒãšã¯ã©ã€ã¢ã³ãã®ç°å¢ãäžè²«ããŠããããšãä¿èšŒããŸããäžççã«å±éããeã³ããŒã¹ã¢ããªã±ãŒã·ã§ã³ãæ³åããŠã¿ãŠãã ããããã€ãã¬ãŒã·ã§ã³äžã«ååèŠçŽ ã®ãµãŒããŒãµã€ããšã¯ã©ã€ã¢ã³ããµã€ãã®IDãäžèŽããªãå ŽåããŠãŒã¶ãŒã¯èª€ã£ãååæ å ±ãèŠãããæ©èœãå£ãããããå¯èœæ§ããããŸãã
- ã³ã³ããŒãã³ãã®ç¶æ ä¿æïŒ å Žåã«ãã£ãŠã¯ãã³ã³ããŒãã³ãã®IDã«åºã¥ããŠãã®ç¶æ ãä¿æããå¿ èŠããããããããŸãããå®å®ããIDã¯ãããŒã¿æ§é å ã§ããŒãšããŠäœ¿çšãããã¬ã³ããªã³ã°ãè¶ããŠç¶æ ã远跡ã»åŸ©å ããããšãã§ããŸãã
- ãã¹ãïŒ å®å®ããIDã¯ãUIãã¹ããå€§å¹ ã«å®¹æã«ããŸãããã¹ã¿ãŒã¯äºæž¬å¯èœãªèå¥åã䜿çšããŠç¹å®ã®èŠçŽ ãã¿ãŒã²ããã«ã§ãããããããä¿¡é Œæ§ãé«ãä¿å®ãããããã¹ãã«ã€ãªãããŸãã倿°ã®ãã±ãŒã«ã§ã³ã³ããŒãã³ãããã¹ãããåœéåãããã¢ããªã±ãŒã·ã§ã³ã§ã¯ãå®å®ããIDã«ãã£ãŠãèšèªã®ããªãšãŒã·ã§ã³ã«é¢ããããã¹ãã®äžè²«æ§ãä¿ãããŸãã
experimental_useOpaqueIdentifier ã®äœ¿ãæ¹
experimental_useOpaqueIdentifier ã®äœ¿çšã¯ç°¡åã§ãã以äžã«åºæ¬çãªäŸã瀺ããŸãïŒ
import { experimental_useOpaqueIdentifier as useOpaqueIdentifier } from 'react';
function MyComponent() {
const id = useOpaqueIdentifier();
return (
<div id={id}>
This is my component.
</div>
);
}
export default MyComponent;
ãã®äŸã§ã¯ãuseOpaqueIdentifier() 㯠MyComponent ã®åã¬ã³ããªã³ã°ãéããŠå®å®ããäžæã®IDãè¿ããŸãããã®IDã¯ã<div> èŠçŽ ã® id 屿§ãšããŠäœ¿çšãããŸãã
é«åºŠãªãŠãŒã¹ã±ãŒã¹ãšäŸ
experimental_useOpaqueIdentifier ãç¹ã«æçãªããã€ãã®é«åºŠãªãŠãŒã¹ã±ãŒã¹ãæ¢ã£ãŠã¿ãŸãããïŒ
1. ã¢ã¯ã»ã·ããªãã£ïŒã¢ã¯ã»ã·ãã«ãªããŒã«ãããã®äœæ
ã¢ã¯ã»ã·ãã«ãªããŒã«ãããã³ã³ããŒãã³ããäœæããå¿
èŠãããã·ããªãªãèããŠã¿ãŸããããããŒã«ãããã¯ãaria-describedby ã䜿çšããŠãããã説æããèŠçŽ ãšé¢é£ä»ããå¿
èŠããããŸãã以äžã¯ experimental_useOpaqueIdentifier ã䜿çšããŠãããå®çŸããæ¹æ³ã§ãïŒ
import { experimental_useOpaqueIdentifier as useOpaqueIdentifier } from 'react';
function Tooltip({
content,
children
}) {
const id = useOpaqueIdentifier();
return (
<>
<span aria-describedby={id}>
{children}
</span>
<div id={id} role="tooltip" style={{ display: 'none' }}>
{content}
</div>
<>
);
}
function MyComponent() {
return (
<Tooltip content="This is the tooltip content.">
Hover over me to see the tooltip.
</Tooltip>
);
}
export default MyComponent;
ãã®äŸã§ã¯ãTooltip ã³ã³ããŒãã³ãã useOpaqueIdentifier ã䜿çšããŠäžæã®IDãçæããŸãããã®IDã¯ãã¿ãŒã²ããèŠçŽ ã® aria-describedby 屿§ãšããŒã«ãããèªäœã® id 屿§ã®äž¡æ¹ã«äœ¿çšãããŸããããã«ãããã³ã³ããŒãã³ããåã¬ã³ããªã³ã°ãããŠããããŒã«ãããããã®ã¿ãŒã²ããèŠçŽ ãšæ£ããé¢é£ä»ããããããšãä¿èšŒãããŸãã
2. Next.jsã§ã®ãµãŒããŒãµã€ãã¬ã³ããªã³ã°ïŒSSRïŒ
Next.jsã®ãããªSSRãã¬ãŒã ã¯ãŒã¯ã䜿çšããå ŽåããµãŒããŒã§çæãããIDãã¯ã©ã€ã¢ã³ãã§çæããããã®ãšäžèŽããããšã確èªããããšãéèŠã§ããexperimental_useOpaqueIdentifier ã¯ããã®ã·ããªãªã§ã®ãã€ãã¬ãŒã·ã§ã³ãšã©ãŒãé²ãã®ã«åœ¹ç«ã¡ãŸããããã¯èªäœãçŽæ¥SSRãåŠçããããã§ã¯ãããŸãããããã®å®å®ããIDçæãæŽåæ§ãç¶æããã®ã«åœ¹ç«ã¡ãŸãã
// pages/index.js
import { experimental_useOpaqueIdentifier as useOpaqueIdentifier } from 'react';
function MyComponent() {
const id = useOpaqueIdentifier();
return (
<div id={id}>
This component is rendered on the server and hydrated on the client.
</div>
);
}
export default MyComponent;
ãã®ç°¡ç¥åãããNext.jsã®äŸã§ã¯ãMyComponent 㯠useOpaqueIdentifier ã䜿çšããŠå®å®ããIDãçæããŸããIDãå®å®ããŠããããããµãŒããŒãšã¯ã©ã€ã¢ã³ãã®äž¡æ¹ã§åãã«ãªãããã€ãã¬ãŒã·ã§ã³ã®äžäžèŽãé²ããŸããããå€§èŠæš¡ã§åœéçãªã¢ããªã±ãŒã·ã§ã³ã§ã¯ããã®äžè²«æ§ã確ä¿ããããšãããŠãŒã¶ãŒã®å Žæããããã¯ãŒã¯ç¶æ³ã«é¢ãããããã¹ãŠã®ãŠãŒã¶ãŒã«ã¹ã ãŒãºãªäœéšãæäŸããããã«äžå¯æ¬ ã«ãªããŸãã
3. åçãªã³ã³ããŒãã³ããªã¹ã
ã³ã³ããŒãã³ãã®åçãªãªã¹ããã¬ã³ããªã³ã°ããå Žåããªã¹ãå
ã®åã¢ã€ãã ã«äžæã®IDãå²ãåœãŠãå¿
èŠããã°ãã°ãããŸããexperimental_useOpaqueIdentifier ã¯ããªã¹ãå
ã®åã³ã³ããŒãã³ãå
ã§ãããã®IDãçæããããã«äœ¿çšã§ããŸãã
import { experimental_useOpaqueIdentifier as useOpaqueIdentifier } from 'react';
function ListItem({
item
}) {
const id = useOpaqueIdentifier();
return (
<li id={id}>
{item.name}
</li>
);
}
function MyListComponent({
items
}) {
return (
<ul>
{items.map(item => (
<ListItem key={item.id} item={item} />
))}
</ul>
);
}
export default MyListComponent;
ãã®äŸã§ã¯ãå ListItem ã³ã³ããŒãã³ãã useOpaqueIdentifier ã䜿çšããŠäžæã®IDãçæããŸãããã®IDã¯ãã¹ã¿ã€ãªã³ã°ãã¢ã¯ã»ã·ããªãã£ããŸãã¯åãªã¹ãã¢ã€ãã ã«äžæã®èå¥åãå¿
èŠãšãããã®ä»ã®ç®çã§äœ¿çšã§ããŸããReactã®å
éšçãªèª¿æŽïŒreconciliationïŒã®ããã«å¥ã® `key` ããããã£ã䜿çšãããŠããããšã«æ³šæããŠãã ããããã㯠useOpaqueIdentifier ã«ãã£ãŠçæãããIDãšã¯*ç°ãªããŸã*ã`key` ããããã£ã¯ReactãDOMãå¹ççã«æŽæ°ããããã«äœ¿çšãããIDã¯ã¢ããªã±ãŒã·ã§ã³åºæã®ç®çã§äœ¿çšãããŸãã
ãã¹ããã©ã¯ãã£ã¹ãšèæ ®äºé
experimental_useOpaqueIdentifier ã¯ID管çã®ããã®åŒ·åãªãœãªã¥ãŒã·ã§ã³ãæäŸããŸããã以äžã®ãã¹ããã©ã¯ãã£ã¹ã«åŸãããšãéèŠã§ãïŒ
- IDãäžéæãªãã®ãšããŠæ±ãïŒ
useOpaqueIdentifierã«ãã£ãŠçæãããIDã®ç¹å®ã®åœ¢åŒãå€ã«äŸåããªãã§ãã ãããããããäžéæãªæååãšããŠæ±ããæå³ãããç®çïŒäŸïŒARIA屿§ãä»ããèŠçŽ ã®é¢é£ä»ãïŒã«ã®ã¿äœ¿çšããŠãã ããã - å®éšçAPIã§ã¯æ³šæããŠäœ¿çšããïŒ
experimental_useOpaqueIdentifierãå®éšçãšããŠããŒã¯ãããŠããããšãèªèããŠãã ãããAPIãšæåã¯å°æ¥ã®ReactãªãªãŒã¹ã§å€æŽãããå¯èœæ§ããããŸããæ³šæããŠäœ¿çšããå¿ èŠã«å¿ããŠã³ãŒããæŽæ°ããæºåãããŠãã ããã - é床ã«äœ¿çšããªãïŒ å®å®ããäžæã®IDãæ¬åœã«å¿
èŠãªå Žåã«ã®ã¿
experimental_useOpaqueIdentifierã䜿çšããŠãã ãããã³ã³ããŒãã³ãã«ãªãŒããŒãããã远å ããå¯èœæ§ããããããäžå¿ èŠã«äœ¿çšããããšã¯é¿ããŠãã ããã - keyãããã㣠vs. IDïŒ Reactãªã¹ãã® `key` ããããã£ã¯ã
experimental_useOpaqueIdentifierã«ãã£ãŠçæãããIDãšã¯ç°ãªãç®çãæããããšãå¿ããªãã§ãã ããã`key` ããããã£ã¯Reactãå éšçãªèª¿æŽã®ããã«äœ¿çšãããã®ã§ãIDã¯ã¢ããªã±ãŒã·ã§ã³åºæã®ç®çã§äœ¿çšãããŸããäŸãã°ããšãŒãããã®ãŠãŒã¶ãŒãååãçŸå°ã®èšèªã§ã¢ã«ãã¡ãããé ã«è¡šç€ºãããå ŽåãReactã® `key` ããããã£ã¯DOMã®æŽæ°ãå¹ççã«åŠçããå®å®ããIDã¯å忝èŒã®ãããªæ©èœã®æ£ããé¢é£ä»ããç¶æããŸãã - ä»£æ¿æ¡ãæ€èšããïŒ
experimental_useOpaqueIdentifierã䜿çšããåã«ãåçŽãªã«ãŠã³ã¿ãŒãUUIDã©ã€ãã©ãªã䜿çšããŠIDãçæãããªã©ãããåçŽãªä»£æ¿æ¡ã§ååãã©ãããæ€èšããŠãã ãããäŸãã°ãSSRãã¢ã¯ã»ã·ããªãã£ãæžå¿µããŠããªãå Žåã¯ãåçŽãªã«ãŠã³ã¿ãŒã§ååãããããŸããã
experimental_useOpaqueIdentifier ã®ä»£æ¿æ¡
experimental_useOpaqueIdentifier ã¯å®å®ããIDãçæãã䟿å©ãªæ¹æ³ãæäŸããŸãããããã€ãã®ä»£æ¿ã¢ãããŒããååšããŸãïŒ
- UUIDã©ã€ãã©ãªïŒ
uuidã®ãããªã©ã€ãã©ãªã䜿çšããŠãæ±çšäžæèå¥åïŒUUIDïŒãçæã§ããŸãããããã®IDã¯äžæã§ããããšãä¿èšŒãããŸãããexperimental_useOpaqueIdentifierã«ãã£ãŠçæããããã®ãããé·ããå¹çãæªãå ŽåããããŸãããããããããã¯åºããµããŒããããŠãããReactã³ã³ããŒãã³ãã®å€ã§IDãçæããå¿ èŠãããã·ããªãªã§åœ¹ç«ã¡ãŸãã - åçŽãªã«ãŠã³ã¿ãŒïŒ ã³ã³ããŒãã³ãå ã§ã®äžææ§ã§ååãªåçŽãªã±ãŒã¹ã§ã¯ãåçŽãªã«ãŠã³ã¿ãŒã䜿çšããŠIDãçæã§ããŸãããããããã®ã¢ãããŒãã¯SSRããIDãåã¬ã³ããªã³ã°ãè¶ããŠå®å®ããå¿ èŠãããã·ããªãªã«ã¯é©ããŠããŸããã
- ã³ã³ããã¹ãããŒã¹ã®IDçæïŒ IDçæã管çãããã®ã³ã³ã·ã¥ãŒããŒã«äžæã®IDãæäŸããã³ã³ããã¹ããããã€ããŒãäœæã§ããŸãããã®ã¢ãããŒãã«ãããID管çãäžå åããpropsãä»ããŠIDãæž¡ãã®ãé¿ããããšãã§ããŸãã
Reactã«ãããID管çã®æªæ¥
experimental_useOpaqueIdentifier ã®å°å
¥ã¯ãReactãå®å®ããID管çã®éèŠæ§ãèªèããŠããããšã瀺ããŠããŸãããã®ããã¯ã¯ãŸã å®éšçã§ãããReactãå°æ¥ãã®èª²é¡ã«ã©ã®ããã«åãçµããã«ã€ããŠã®è²ŽéãªæŽå¯ãæäŸããŸããå°æ¥ã®ReactãªãªãŒã¹ã§ã¯ãIDçæã®ããã®ããå
ç¢ã§å®å®ããAPIãç»å Žããå¯èœæ§ãé«ãã§ããã°ããŒãã«ãªReactã³ãã¥ããã£ã¯ãIDãã¢ã¯ã»ã·ããªãã£ãSSRã®ããè¯ãæ±ãæ¹ãç©æ¥µçã«æ¢æ±ã»è°è«ããŠãããå
ç¢ã§ã¢ã¯ã»ã·ãã«ãªReactã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ããããŸã§ä»¥äžã«å®¹æã«ãªãæªæ¥ã«è²¢ç®ããŠããŸãã
çµè«
experimental_useOpaqueIdentifier ã¯ãReactã³ã³ããŒãã³ãã§å®å®ããIDã管çããããã®è²ŽéãªããŒã«ã§ããäžæã®èå¥åãçæããããã»ã¹ãç°¡çŽ åããç¹ã«ã¢ã¯ã»ã·ããªãã£ããµãŒããŒãµã€ãã¬ã³ããªã³ã°ãé¢ããã·ããªãªã§ãã¬ã³ããªã³ã°ãè¶ããäžè²«æ§ã確ä¿ããã®ã«åœ¹ç«ã¡ãŸãããã®å®éšçãªæ§è³ªãèªèããããšã¯éèŠã§ãããexperimental_useOpaqueIdentifier ã¯Reactã«ãããID管çã®æªæ¥ãå£éèŠããå€ãã®äžè¬çãªãŠãŒã¹ã±ãŒã¹ã«å®çšçãªè§£æ±ºçãæäŸããŸãããã®å©ç¹ãå¶éããã¹ããã©ã¯ãã£ã¹ãçè§£ããããšã§ãexperimental_useOpaqueIdentifier ãæŽ»çšããŠãããå
ç¢ã§ãã¢ã¯ã»ã·ãã«ã§ãä¿å®ããããReactã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸããReactã®é²åã«ç®ãå
ãããæ°ããæ¹è¯ãããAPIãå©çšå¯èœã«ãªã£ããšãã«ã³ãŒããé©å¿ãããæºåãããŠããããšãå¿ããªãã§ãã ããã