Reactã®cloneElementã®ãã¯ãŒãè§£æŸããå¹ççãªèŠçŽ å€æŽãåçãªUIäœæãã³ã³ããŒãã³ãã®åå©çšæ§åäžãå®çŸããŸããããå®è·µçãªäŸãšãã¹ããã©ã¯ãã£ã¹ãæ¢ããŸãã
React cloneElementïŒåçãªUIãå®çŸããèŠçŽ å€æŽã®ãã¹ã¿ãŒã¬ã€ã
React.cloneElement
ã¯ãReactéçºè
ã®æŠåšåº«ã«ãã匷åãªããŒã«ã§ããæ¢åã®èŠçŽ ã«åºã¥ããŠæ°ããReactèŠçŽ ãäœæããå
ã®èŠçŽ ãçŽæ¥å€æŽããããšãªãããã®propsãåèŠçŽ ã远å ã»å€æŽããããšãã§ããŸãããã®äžå€æ§ïŒã€ãã¥ãŒã¿ããªãã£ïŒã¯Reactã®æ žãšãªãååã§ãããäºæž¬å¯èœã§ä¿å®æ§ã®é«ãã³ãŒãã«è²¢ç®ããŸãããã®å
æ¬çãªã¬ã€ãã§ã¯ãcloneElement
ã®è€éãªè©³çްãæãäžãããã®ãŠãŒã¹ã±ãŒã¹ãå©ç¹ããã¹ããã©ã¯ãã£ã¹ãæ¢ããŸãã
ReactèŠçŽ ãšã³ã³ããŒãã³ãã®çè§£
cloneElement
ãæ·±ãæãäžããåã«ãReactèŠçŽ ãšã³ã³ããŒãã³ãã®åºæ¬çãªæŠå¿µãçè§£ããããšãäžå¯æ¬ ã§ãã
ReactèŠçŽ : ReactèŠçŽ ã¯ãç»é¢ã«äœã衚瀺ãããããèšè¿°ãããã¬ãŒã³ãªJavaScriptãªããžã§ã¯ãã§ãã軜éã§äžå€ã§ããå®éã®DOMããŒãã®èšèšå³ãšèããŠãã ããã
Reactã³ã³ããŒãã³ã: Reactã³ã³ããŒãã³ãã¯ãåå©çšå¯èœã§èªå·±å®çµããUIã®åäœã§ãããããã¯é¢æ°ã³ã³ããŒãã³ãïŒåçŽãªJavaScript颿°ïŒãŸãã¯ã¯ã©ã¹ã³ã³ããŒãã³ãïŒã©ã€ããµã€ã¯ã«ã¡ãœãããæã€JavaScriptã¯ã©ã¹ïŒã®ããããã«ãªããŸããã³ã³ããŒãã³ãã¯ReactèŠçŽ ãã¬ã³ããªã³ã°ããReactã¯ããã䜿çšããŠDOMãæŽæ°ããŸãã
cloneElement
ã¯ReactèŠçŽ ã«å¯ŸããŠæäœãè¡ãããããã®èšèšå³ãã¬ã³ããªã³ã°ãããåã«å€æŽããããšãå¯èœã«ããŸãã
React.cloneElementãšã¯äœãïŒ
React.cloneElement(element, props, ...children)
ã¯ãæäŸãããelement
ã«åºã¥ããŠæ°ããReactèŠçŽ ãäœæããè¿ããŸããããã¯åºæ¬çã«å
ã®èŠçŽ ãè€è£œããŸããããã®propsãäžæžãããããæ°ããåèŠçŽ ã远å ãããã§ããŸããèŠããŠããã¹ãéèŠãªç¹ïŒ
- å ã®èŠçŽ ã倿ŽããŸããã
- æ°ããReactèŠçŽ ãè¿ããŸãã
- æ°ããpropsãå ã®èŠçŽ ã®propsãšããŒãžããŸããç«¶åãããå Žåãæ°ããpropsãåªå ãããŸãã
- ã¯ããŒã³ãããèŠçŽ ã«æ°ããåèŠçŽ ã远å ã§ããŸãã
æ§æã®åè§£ïŒ
æ§æãåè§£ããŠã¿ãŸãããïŒ
React.cloneElement(element, props, ...children)
element
: ã¯ããŒã³ãããReactèŠçŽ ãprops
: 远å ãŸãã¯äžæžããããæ°ããpropsãå«ããªããžã§ã¯ãã...children
: ã¯ããŒã³ãããèŠçŽ ã«è¿œå ããä»»æã®åèŠçŽ ããããã¯ã`props.children`ã«æç€ºçã«å«ããªãéããæ¢åã®åèŠçŽ ã眮ãæããŸãã
React.cloneElementã®ãŠãŒã¹ã±ãŒã¹
cloneElement
ã¯ãç¹ã«ä»¥äžã®ãããªã·ããªãªã§åœ¹ç«ã¡ãŸãïŒ
- åã³ã³ããŒãã³ãã®propsã倿ŽããïŒ åå©çšå¯èœãªãã¿ã³ã³ã³ããŒãã³ãããããã³ã³ããã¹ãã«åºã¥ããŠãã®
onClick
ãã³ãã©ãã¹ã¿ã€ã«ãåçã«å€æŽãããå Žåãæ³åããŠãã ããã - æ¢åã®ã³ã³ããŒãã³ãã«ã©ãããŒã远å ããïŒ è¿œå ã®æ©èœãã¹ã¿ã€ãªã³ã°ãæäŸããé«éã³ã³ããŒãã³ãïŒHOCïŒã§ã³ã³ããŒãã³ããã©ãããããå ŽåããããŸãã
- åçãªã¬ã€ã¢ãŠããäœæããïŒ
cloneElement
ã䜿çšããŠãç»é¢ãµã€ãºããã®ä»ã®èŠå ã«åºã¥ããŠã³ã³ããŒãã³ãã®ã¬ã€ã¢ãŠããã¹ã¿ã€ãªã³ã°ã調æŽã§ããŸãã - ããããããªãªã³ã°ã®ä»£æ¿ïŒæ³šæããŠäœ¿çšïŒïŒ ç¹å®ã®ã·ããªãªã§éå°ãªããããããªãªã³ã°ãé¿ããããã«äœ¿çšã§ããŸããããããé床ãªäœ¿çšã¯ã³ãŒãã®çè§£ãšä¿å®ãå°é£ã«ããå¯èœæ§ããããŸãã
cloneElementã®å®è·µçãªäŸ
cloneElement
ãã©ã®ããã«å¹æçã«äœ¿çšã§ãããã説æããããã«ãããã€ãã®å®è·µçãªäŸãæ¢ã£ãŠã¿ãŸãããã
äŸ1ïŒãã¿ã³ã®propsã倿Žãã
ã·ã³ãã«ãªãã¿ã³ã³ã³ããŒãã³ããèããŠã¿ãŸãããïŒ
function MyButton(props) {
return ;
}
ã§ã¯ããã®ãã¿ã³ã®ä¿®æ£çãäœæããç°ãªãonClick
ãã³ãã©ãšè¿œå ã®ã¹ã¿ã€ã«ãé©çšãããå ŽåãèããŠã¿ãŸãããïŒ
import React from 'react';
function MyButton(props) {
return ;
}
function App() {
const handleClick = () => {
alert('Button clicked!');
};
const buttonStyle = {
backgroundColor: 'lightblue',
padding: '10px',
border: 'none',
borderRadius: '5px',
cursor: 'pointer',
};
return (
console.log('Original button clicked')}>Original Button
{React.cloneElement(
Cloned Button ,
{
onClick: handleClick,
style: buttonStyle
}
)}
);
}
export default App;
ãã®äŸã§ã¯ãcloneElement
ã¯æå®ãããonClick
ãã³ãã©ãšstyle
ãæã€æ°ãããã¿ã³èŠçŽ ãäœæããå
ã®ãã¿ã³ã®ããããã£ã广çã«äžæžãããŸããã¯ããŒã³ããããã¿ã³ã¯ãæ°Žè²ã®èæ¯ãäžžã¿ã垯ã³ãè§ããããŠç°ãªãã¯ãªãã¯åäœã§è¡šç€ºãããŸãã
äŸ2ïŒã©ãããŒã³ã³ããŒãã³ãã®è¿œå
ããã£ã³ã°ã远å ããdivã§ã©ãããããã³ã³ããŒãã³ãããããšããŸãïŒ
function MyComponent() {
return This is my component.
;
}
cloneElement
ã䜿çšããŠã©ãããŒã远å ã§ããŸãïŒ
import React from 'react';
function MyComponent() {
return This is my component.
;
}
function App() {
const wrapperStyle = {
padding: '20px',
border: '1px solid black'
};
return (
{React.cloneElement(
,
{
style: wrapperStyle,
children: (
)
}
)}
);
}
export default App;
泚ïŒãã®äŸã¯æ©èœã瀺ããã®ã§ãããã©ãããŒã远å ããçæ³çãªæ¹æ³ã§ã¯ãããŸãããã»ãšãã©ã®ç¶æ³ã§ã¯ãå°çšã®ã©ãããŒã³ã³ããŒãã³ããäœæããæ¹ãè¯ãå®è·µã§ãã
äŸ3ïŒæ¡ä»¶ä»ãã§ã®Propã®å€æŽ
ããã¯ãcloneElement
ã䜿çšããŠæ¡ä»¶ä»ãã§propsã倿Žããæ¹æ³ã®äŸã§ããç¹å®ã®æ¡ä»¶ã«åºã¥ããŠãã¿ã³ãç¡å¹ã«ãããã·ããªãªãæ³åããŠãã ããã
import React, { useState } from 'react';
function MyButton(props) {
return ;
}
function App() {
const [isDisabled, setIsDisabled] = useState(false);
const toggleDisabled = () => {
setIsDisabled(!isDisabled);
};
return (
alert('Clicked!')} disabled={isDisabled}>Click Me
);
}
export default App;
äŸ4ïŒåèŠçŽ ã®æäœ
cloneElement
ã¯ãã³ã³ããŒãã³ãã®åèŠçŽ ãæ±ãéã«åŒ·åã§ããã¢ã€ãã ã®ãªã¹ããã¬ã³ããªã³ã°ããã³ã³ããŒãã³ãããããåã¢ã€ãã ã«ç¹å®ã®propã远å ããããšããŸãã
import React from 'react';
function ListItem(props) {
return {props.children} ;
}
function MyList(props) {
return (
{React.Children.map(props.children, child => {
return React.cloneElement(child, {
style: { color: 'blue' }
});
})}
);
}
function App() {
return (
Item 1
Item 2
Item 3
);
}
export default App;
ãã®äŸã§ã¯ãReact.Children.map
ãMyList
ã³ã³ããŒãã³ãã®åèŠçŽ ãå埩åŠçããŸããååèŠçŽ ïŒListItem
ïŒã«å¯ŸããŠãcloneElement
ã䜿çšããŠstyle
ããããã远å ããããã¹ãã®è²ãéã«èšå®ããŸããããã«ãããã³ã³ããŒãã³ãã®ãã¹ãŠã®åèŠçŽ ã«ã¹ã¿ã€ãªã³ã°ããã®ä»ã®å€æŽãç°¡åã«é©çšã§ããŸãã
cloneElementã䜿çšããããã®ãã¹ããã©ã¯ãã£ã¹
cloneElement
ã¯äŸ¡å€ã®ããããŒã«ã§ãããã³ãŒããé床ã«è€éã«ããªãããã«æ
éã«äœ¿çšããããšãéèŠã§ããå¿ã«çããŠããã¹ããã¹ããã©ã¯ãã£ã¹ãããã€ã玹ä»ããŸãïŒ
- æ§ããã«äœ¿çšããïŒ
cloneElement
ã®ä¹±çšã¯ãèªã¿ã«ããçè§£ãã«ããã³ãŒãã«ã€ãªããå¯èœæ§ããããŸããããããããªãªã³ã°ãã³ã³ããã¹ããªã©ãããé©åãªä»£æ¿ã¢ãããŒããæ€èšããŠãã ããã - ã·ã³ãã«ã«ä¿ã€ïŒ
cloneElement
ã®åŒã³åºãå ã«è€éãªããžãã¯ãé¿ããŠãã ãããè€éãªæäœãå®è¡ããå¿ èŠãããå Žåã¯ãå°çšã®ã³ã³ããŒãã³ãããã«ããŒé¢æ°ãäœæããããšãæ€èšããŠãã ããã - keyã䜿çšããïŒ ã«ãŒããmap颿°å
ã§èŠçŽ ãã¯ããŒã³ããå Žåã¯ãåã¯ããŒã³ãããèŠçŽ ã«äžæã®
key
ãããããæäŸããŠãã ãããããã«ãããReactãå¹ççã«DOMãæŽæ°ã§ããŸãã - ã³ãŒããææžåããïŒ ã³ãŒãå
ã§ã®
cloneElement
ã®ç®çãšäœ¿çšæ³ãæç¢ºã«ææžåããä»ã®äººïŒãããŠèªåèªèº«ïŒãçè§£ããããããŸãã - ä»£æ¿æ¡ãæ€èšããïŒ å Žåã«ãã£ãŠã¯ãã¬ã³ããŒãããããé«éã³ã³ããŒãã³ãã䜿çšããæ¹ãã
cloneElement
ãå€çšãããããã¯ãªãŒã³ã§ä¿å®æ§ã®é«ããœãªã¥ãŒã·ã§ã³ãæäŸããããšããããŸãã
cloneElementã®ä»£æ¿æ¡
cloneElement
ã¯æè»æ§ãæäŸããŸãããä»ã®ãã¿ãŒã³ã§ãåæ§ã®çµæãéæã§ããä¿å®æ§ãå¯èªæ§ãåäžããå¯èœæ§ããããŸãïŒ
- ã¬ã³ããŒããããïŒ ãã®ãã¿ãŒã³ã§ã¯ãã³ã³ããŒãã³ããã¬ã³ããªã³ã°ã«äœ¿çšãã颿°ããããããšããŠæž¡ããŸããããã«ããã芪ã³ã³ããŒãã³ããåã³ã³ããŒãã³ãã®ã¬ã³ããªã³ã°ãå¶åŸ¡ã§ããŸãã
- é«éã³ã³ããŒãã³ãïŒHOCïŒïŒ HOCã¯ãã³ã³ããŒãã³ããåãåããæ°ãã匷åãããã³ã³ããŒãã³ããè¿ã颿°ã§ããããã¯ãèªèšŒããã®ã³ã°ãªã©ã®æšªæçãªé¢å¿äºã远å ããã®ã«åœ¹ç«ã¡ãŸãã
- Context APIïŒ Reactã®Context APIã¯ãããŒãããŠãŒã¶ãŒèªèšŒã®è©³çްãªã©ã®å€ããããªãŒã®ãã¹ãŠã®ã¬ãã«ã§æç€ºçã«ãããããæž¡ãããšãªãã³ã³ããŒãã³ãéã§å ±æããæ¹æ³ãæäŸããŸãã
ããããèœãšã穎ãšãã®åé¿æ¹æ³
cloneElement
ã广çã«äœ¿çšããã«ã¯ãããã€ãã®äžè¬çãªèœãšã穎ãçè§£ããå¿
èŠããããŸãïŒ
- åèŠçŽ ã®æž¡ãå¿ãïŒ èŠçŽ ãã¯ããŒã³ãããšãã¯ããã®åèŠçŽ ãæ£ããåŠçããããšãå¿ããªãã§ãã ãããå ã®åèŠçŽ ãæç€ºçã«æž¡ãããæ°ããåèŠçŽ ãæäŸããªãå Žåããããã¯å€±ãããŸãã
- Propã®ç«¶åïŒ
cloneElement
ã«æž¡ãããæ°ããpropsãå ã®propsãšç«¶åããå Žåãåžžã«æ°ããpropsãå ãäžæžãããŸããäºæããªãçµæãé¿ããããã«ããã®åäœã«æ³šæããŠãã ããã - ããã©ãŒãã³ã¹ã®åé¡ïŒ ç¹ã«é »ç¹ã«æŽæ°ãããã³ã³ããŒãã³ãã§ã®
cloneElement
ã®ä¹±çšã¯ãããã©ãŒãã³ã¹ã®åé¡ã«ã€ãªããå¯èœæ§ããããŸããã¢ããªã±ãŒã·ã§ã³ããããã¡ã€ãªã³ã°ããŠãããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ãã察åŠããŠãã ããã
cloneElementãšãµãŒããŒãµã€ãã¬ã³ããªã³ã°ïŒSSRïŒ
cloneElement
ã¯ãµãŒããŒãµã€ãã¬ã³ããªã³ã°ïŒSSRïŒãšã·ãŒã ã¬ã¹ã«é£æºããŸããReactèŠçŽ ã¯åãªãJavaScriptãªããžã§ã¯ãã§ããããããµãŒããŒäžã§ç°¡åã«ã·ãªã¢ã©ã€ãºããŠã¬ã³ããªã³ã°ã§ããŸãã
åœéåã«é¢ããèæ ®äºé
åœéåãããã¢ããªã±ãŒã·ã§ã³ã§äœæ¥ããå ŽåãcloneElement
ãããã¹ãããã®ä»ã®ãã±ãŒã«åºæã®ããããã£ã«ã©ã®ããã«åœ±é¿ããããèæ
®ããŠãã ãããçŸåšã®ãã±ãŒã«ã«åºã¥ããŠpropsã調æŽããå¿
èŠããããããããŸãããããšãã°ããŠãŒã¶ãŒã®èšèªã«åºã¥ããŠã¢ã¯ã»ã·ããªãã£ã®ããã®`aria-label`屿§ãåçã«èšå®ã§ããŸãã
ã¢ã¯ã»ã·ããªãã£ã«é¢ããèæ ®äºé
cloneElement
ã䜿çšããŠèŠçŽ ã倿Žããéã¯ãæå³ããã¢ã¯ã»ã·ããªãã£ãæãªããªãããã«æ³šæããŠãã ãããæ°ããèŠçŽ ãé©åãªARIA屿§ãšã»ãã³ãã£ãã¯ãªHTMLãç¶æããŠããããšã確èªããŠãã ãããããšãã°ãåçã«ãã¿ã³ã远å ããå Žåãã¹ã¯ãªãŒã³ãªãŒããŒã®ããã«é©åãª`aria-label`ã`aria-describedby`屿§ãããããšã確èªããŠãã ããã
çµè«
React.cloneElement
ã¯ãReactèŠçŽ ãæäœããåçãªUIãäœæããããã®åŒ·åãªããŒã«ã§ãããã®èœåãšéçãçè§£ããããšã§ãããæè»ã§ãåå©çšå¯èœã§ãä¿å®æ§ã®é«ãã³ãŒããæžãããã«æŽ»çšã§ããŸããæ
éã«äœ¿çšãã代æ¿ãã¿ãŒã³ãæ€èšããåžžã«ã³ãŒãã®æçããšããã©ãŒãã³ã¹ãåªå
ããããšãå¿ããªãã§ãã ããã
cloneElement
ããã¹ã¿ãŒããããšã§ãReactã¢ããªã±ãŒã·ã§ã³ã«å¯Ÿããæ°ããã¬ãã«ã®å¶åŸ¡ãè§£æŸããçã«åçã§é
åçãªãŠãŒã¶ãŒäœéšãåµé ã§ããŸãã