Reactã®refã³ãŒã«ããã¯ã®æé©åã®ãã¥ã¢ã³ã¹ãæ¢æ±ããŸããäºåºŠçºç«ããçç±ãuseCallbackã§ãããé²ãæ¹æ³ãè€éãªã¢ããªã®ããã©ãŒãã³ã¹ããã¹ã¿ãŒããŸãããã
Reactã®Refã³ãŒã«ããã¯ããã¹ã¿ãŒããïŒããã©ãŒãã³ã¹æé©åã®ããã®ç©¶æ¥µã¬ã€ã
çŸä»£ã®ãŠã§ãéçºã®äžçã§ã¯ãããã©ãŒãã³ã¹ã¯åãªãæ©èœã§ã¯ãªããå¿ èŠäžå¯æ¬ ãªãã®ã§ããReactã䜿çšããéçºè ã«ãšã£ãŠãé«éã§å¿çæ§ã®é«ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãæ§ç¯ããããšãäž»ãªç®æšã§ããReactã®ä»®æ³DOMãšå調æŽã¢ã«ãŽãªãºã ãå€ãã®è² è·ãåŠçããŸãããç¹å®ã®ãã¿ãŒã³ãšAPIã§ã¯ãæé«ã®ããã©ãŒãã³ã¹ãåŒãåºãããã«æ·±ãçè§£ãäžå¯æ¬ ã§ãããã®ãããªé åã®1ã€ããrefsã®ç®¡çãå ·äœçã«ã¯ããã°ãã°èª€è§£ãããã³ãŒã«ããã¯refsã®åäœã§ãã
Refsã¯ãrenderã¡ãœããã§äœæãããDOMããŒããŸãã¯ReactèŠçŽ ã«ã¢ã¯ã»ã¹ããæ¹æ³ãæäŸããŸããããã¯ããã©ãŒã«ã¹ã®ç®¡çãã¢ãã¡ãŒã·ã§ã³ã®ããªã¬ãŒããµãŒãããŒãã£ã®DOMã©ã€ãã©ãªãšã®çµ±åãªã©ã®ã¿ã¹ã¯ã«äžå¯æ¬ ãªãšã¹ã±ãŒããããã§ããuseRefã颿°åã³ã³ããŒãã³ãã®åçŽãªã±ãŒã¹ã®æšæºã«ãªã£ãŠããŸãããã³ãŒã«ããã¯refsã¯ãåç
§ããã€èšå®ããã³èšå®è§£é€ããããããã匷åã«ããã现ããå¶åŸ¡ã§ããŸãããã ãããã®åã«ã¯åŸ®åŠãªç¹ããããŸããã³ãŒã«ããã¯refã¯ãã³ã³ããŒãã³ãã®ã©ã€ããµã€ã¯ã«äžã«è€æ°åçºç«ããå¯èœæ§ããããæ£ããåŠçããªããšãããã©ãŒãã³ã¹ã®ããã«ããã¯ããã°ã«ã€ãªããå¯èœæ§ããããŸãã
ãã®å æ¬çãªã¬ã€ãã§ã¯ãReactã®refã³ãŒã«ããã¯ããããããã解説ããŸãã以äžãæ¢æ±ããŸãïŒ
- ã³ãŒã«ããã¯refsãšã¯äœããä»ã®refã¿ã€ããšã©ã®ããã«ç°ãªããã
- ã³ãŒã«ããã¯refsã2ååŒã³åºãããïŒæåã¯
nullã§ã次ã«èŠçŽ ã§ïŒäž»ãªçç±ã - refã³ãŒã«ããã¯ã«ã€ã³ã©ã€ã³é¢æ°ã䜿çšããããšã®ããã©ãŒãã³ã¹ã®èœãšã穎ã
useCallbackããã¯ã䜿çšããæé©åã®æ±ºå®çãªè§£æ±ºçã- äŸåé¢ä¿ã®åŠçãšå€éšã©ã€ãã©ãªãšã®çµ±åã®ããã®é«åºŠãªãã¿ãŒã³ã
ãã®èšäºã®çµãããŸã§ã«ãèªä¿¡ãæã£ãŠã³ãŒã«ããã¯refsã䜿çšããç¥èãç¿åŸããReactã¢ããªã±ãŒã·ã§ã³ãå ç¢ã§ããã ãã§ãªããéåžžã«é«æ§èœã§ããããšãä¿èšŒããŸãã
ç°¡åãªåŸ©ç¿ïŒã³ãŒã«ããã¯Refsãšã¯ïŒ
æé©åã«å
¥ãåã«ãã³ãŒã«ããã¯refãšã¯äœããç°¡åã«åŸ©ç¿ããŸããããuseRef()ãŸãã¯React.createRef()ã§äœæãããrefãªããžã§ã¯ããæž¡ã代ããã«ãref屿§ã«é¢æ°ãæž¡ããŸãããã®é¢æ°ã¯ãã³ã³ããŒãã³ãã®ããŠã³ãæããã³ã¢ã³ããŠã³ãæã«Reactã«ãã£ãŠå®è¡ãããŸãã
Reactã¯ãã³ã³ããŒãã³ããããŠã³ãããããšãã«ãDOMèŠçŽ ãåŒæ°ãšããŠrefã³ãŒã«ããã¯ãåŒã³åºããã³ã³ããŒãã³ããã¢ã³ããŠã³ãããããšãã«ãnullãåŒæ°ãšããŠåŒã³åºããŸããããã«ãããåç
§ãå©çšå¯èœã«ãªãæ£ç¢ºãªç¬éããŸãã¯ç Žæ£ãããããšããŠããç¬éã«ãæ£ç¢ºãªå¶åŸ¡ãè¡ãããšãã§ããŸãã
颿°åã³ã³ããŒãã³ãã®ç°¡åãªäŸã次ã«ç€ºããŸãïŒ
import React, { useState } from 'react';
function TextInputWithFocusButton() {
let textInput = null;
const setTextInputRef = element => {
console.log('Ref callback fired with:', element);
textInput = element;
};
const focusTextInput = () => {
// Focus the text input using the raw DOM API
if (textInput) textInput.focus();
};
return (
<div>
<input type="text" ref={setTextInputRef} />
<button onClick={focusTextInput}>
Focus the text input
</button>
</div>
);
}
ãã®äŸã§ã¯ãsetTextInputRefãã³ãŒã«ããã¯refã§ããããã¯ã<input>èŠçŽ ãã¬ã³ããªã³ã°ããããšãã«åŒã³åºãããæ ŒçŽããŠåŸã§focus()ãåŒã³åºãããã«äœ¿çšã§ããŸãã
ã³ã¢ã®åé¡ïŒãªãRefã³ãŒã«ããã¯ã¯2åçºç«ããã®ã§ããïŒ
éçºè ãæ··ä¹±ãããäžå¿çãªåäœã¯ãã³ãŒã«ããã¯ã®2åã®åŒã³åºãã§ããã³ãŒã«ããã¯refãæã€ã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããããšãã³ãŒã«ããã¯é¢æ°ã¯éåžžãé£ç¶ããŠ2ååŒã³åºãããŸãïŒ
- æåã®åŒã³åºãïŒåŒæ°ãšããŠ
nullã䜿çšã - 2åç®ã®åŒã³åºãïŒåŒæ°ãšããŠDOMèŠçŽ ã€ã³ã¹ã¿ã³ã¹ã䜿çšã
ããã¯ãã°ã§ã¯ãããŸãããããã¯ReactããŒã ã«ããæå³çãªèšèšäžã®éžæã§ããnullã䜿çšããåŒã³åºãã¯ã以åã®refïŒååšããå ŽåïŒããã¿ãããããŠããããšãæå³ããŸããããã«ãããã¯ãªãŒã³ã¢ããæäœãå®è¡ããéèŠãªæ©äŒãåŸãããŸããããšãã°ã以åã®ã¬ã³ããªã³ã°ã§ããŒãã«ã€ãã³ããªã¹ããŒãã¢ã¿ããããå ŽåãnullåŒã³åºãã¯ãæ°ããããŒããã¢ã¿ãããããåã«åé€ããã®ã«æé©ãªã¿ã€ãã³ã°ã§ãã
ãã ããåé¡ã¯ãã®ããŠã³ã/ã¢ã³ããŠã³ããµã€ã¯ã«ã§ã¯ãããŸãããæ¬åœã®ããã©ãŒãã³ã¹ã®åé¡ã¯ãã³ã³ããŒãã³ãã®ç¶æ ãrefèªäœãšã¯ãŸã£ããé¢ä¿ã®ãªãæ¹æ³ã§æŽæ°ãããå Žåã§ãããã®2åã®çºç«ããã¹ãŠã®åã¬ã³ããªã³ã°ã§çºçããå Žåã«çºçããŸãã
ã€ã³ã©ã€ã³é¢æ°ã®èœãšã穎
åã¬ã³ããªã³ã°ããã颿°åã³ã³ããŒãã³ãå ã§ãäžèŠç¡å®³ã«èŠãããã®å®è£ ãæ€èšããŠãã ããïŒ
import React, { useState } from 'react';
function FrequentUpdatesComponent() {
const [count, setCount] = useState(0);
return (
<div>
<h3>Counter: {count}</h3>
<button onClick={() => setCount(c => c + 1)}>Increment</button>
<div
ref={(node) => {
// This is an inline function!
console.log('Ref callback fired with:', node);
}}
>
I am the referenced element.
</div>
</div>
);
}
ãã®ã³ãŒããå®è¡ããŠãIncrementããã¿ã³ãã¯ãªãã¯ãããšããã¹ãŠã®ã¯ãªãã¯ã§ã³ã³ãœãŒã«ã«æ¬¡ã®ããã«è¡šç€ºãããŸãïŒ
Ref callback fired with: null
Ref callback fired with: <div>...</div>
ãªããããªãã®ã§ããããïŒã¬ã³ããªã³ã°ããšã«ãrefããããã£ã®çæ°ãã颿°ã€ã³ã¹ã¿ã³ã¹ãäœæããŠããããã§ãïŒ(node) => { ... }ãReactã¯ãå調æŽããã»ã¹äžã«ã以åã®ã¬ã³ããªã³ã°ã®propsãçŸåšã®propsãšæ¯èŒããŸããrefããããã£ã倿ŽãããïŒå€ã颿°ã€ã³ã¹ã¿ã³ã¹ããæ°ãã颿°ã€ã³ã¹ã¿ã³ã¹ãžïŒããšãããããŸããReactã®å¥çŽã¯æç¢ºã§ããrefã³ãŒã«ããã¯ã倿Žãããå Žåã¯ãæåã«nullã§åŒã³åºããŠå€ãrefãã¯ãªã¢ããæ¬¡ã«DOMããŒãã§åŒã³åºããŠæ°ããrefãèšå®ããå¿
èŠããããŸããããã«ãããåã¬ã³ããªã³ã°ããšã«äžèŠãªã¯ãªãŒã³ã¢ãã/ã»ããã¢ãããµã€ã¯ã«ãããªã¬ãŒãããŸãã
åçŽãªconsole.logã®å Žåãããã¯ããããªããã©ãŒãã³ã¹ã®äœäžã§ããããããã³ãŒã«ããã¯ãé«äŸ¡ãªåŠçãè¡ããšæ³åããŠãã ããïŒ
- è€éãªã€ãã³ããªã¹ããŒã®ã¢ã¿ãããšãã¿ããïŒäŸïŒ`scroll`ã`resize`ïŒã
- éããµãŒãããŒãã£ã©ã€ãã©ãªã®åæåïŒD3.jsãã£ãŒãããããã³ã°ã©ã€ãã©ãªãªã©ïŒã
- ã¬ã€ã¢ãŠãã®ãªãããŒãåŒãèµ·ããDOM枬å®ã®å®è¡ã
ãã®ããžãã¯ããã¹ãŠã®ç¶æ æŽæ°ã§å®è¡ãããšãã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãèããäœäžãã远跡ãå°é£ãªåŸ®åŠãªãã°ãçºçããå¯èœæ§ããããŸãã
解決çïŒ`useCallback`ã§ã¡ã¢åãã
ãã®åé¡ã®è§£æ±ºçã¯ã倿Žãæç€ºçã«èŠæ±ããªãéããReactãåã¬ã³ããªã³ã°éã§refã³ãŒã«ããã¯ã«ãŸã£ããåã颿°ã€ã³ã¹ã¿ã³ã¹ãåãåãããã«ããããšã§ããããã¯ãuseCallbackããã¯ã«æé©ãªäœ¿çšäŸã§ãã
useCallbackã¯ãã³ãŒã«ããã¯é¢æ°ã®ã¡ã¢åãããããŒãžã§ã³ãè¿ããŸãããã®ã¡ã¢åãããããŒãžã§ã³ã¯ãäŸåé¢ä¿é
åå
ã®äŸåé¢ä¿ã®ããããã倿Žãããå Žåã«ã®ã¿å€æŽãããŸãã空ã®äŸåé¢ä¿é
åïŒ[]ïŒãæäŸããããšã«ãããã³ã³ããŒãã³ãã®æå¹æéå
šäœã«ããã£ãŠæ°žç¶åããå®å®ãã颿°ãäœæã§ããŸãã
useCallbackã䜿çšããŠãåã®äŸããªãã¡ã¯ã¿ãªã³ã°ããŸãããïŒ
import React, { useState, useCallback } from 'react';
function OptimizedComponent() {
const [count, setCount] = useState(0);
// Create a stable callback function with useCallback
const myRefCallback = useCallback(node => {
// This logic now runs only when the component mounts and unmounts
console.log('Ref callback fired with:', node);
if (node !== null) {
// You can perform setup logic here
console.log('Element is mounted!');
}
}, []); // <-- Empty dependency array means the function is created only once
return (
<div>
<h3>Counter: {count}</h3>
<button onClick={() => setCount(c => c + 1)}>Increment</button>
<div ref={myRefCallback}>
I am the referenced element.
</div>
</div>
);
}
ããã§ããã®æé©åãããããŒãžã§ã³ãå®è¡ãããšãã³ã³ãœãŒã«ãã°ã¯åèšã§2åãã衚瀺ãããŸããïŒ
- ã³ã³ããŒãã³ããæåã«ããŠã³ãããããšãïŒ
Ref callback fired with: <div>...</div>ïŒã - ã³ã³ããŒãã³ããã¢ã³ããŠã³ãããããšãïŒ
Ref callback fired with: nullïŒã
ãIncrementããã¿ã³ãã¯ãªãã¯ããŠããrefã³ãŒã«ããã¯ã¯ããªã¬ãŒãããªããªããŸããåã¬ã³ããªã³ã°ããšã«äžèŠãªã¯ãªãŒã³ã¢ãã/ã»ããã¢ãããµã€ã¯ã«ãæ£åžžã«é²æ¢ããŸãããReactã¯ãåŸç¶ã®ã¬ã³ããªã³ã°ã§refããããã£ã«åã颿°ã€ã³ã¹ã¿ã³ã¹ã衚瀺ãã倿Žãå¿
èŠãªãããšãæ£ãã倿ããŸãã
é«åºŠãªã·ããªãªãšãã¹ããã©ã¯ãã£ã¹
空ã®äŸåé¢ä¿é
åã¯äžè¬çã§ãããrefã³ãŒã«ããã¯ãpropsãŸãã¯ç¶æ
ã®å€æŽã«å¯Ÿå¿ããå¿
èŠãããã·ããªãªããããŸããããã¯ãuseCallbackã®äŸåé¢ä¿é
åã®åãçã«çºæ®ãããå Žæã§ãã
ã³ãŒã«ããã¯ã§ã®äŸåé¢ä¿ã®åŠç
ç¶æ ãŸãã¯propsã®äžéšã«äŸåããããžãã¯ãrefã³ãŒã«ããã¯å ã§å®è¡ããå¿ èŠããããšæ³åããŠãã ãããããšãã°ãçŸåšã®ããŒãã«åºã¥ããŠ`data-`屿§ãèšå®ããŸãã
function ThemedComponent({ theme }) {
const [internalState, setInternalState] = useState(0);
const themedRefCallback = useCallback(node => {
if (node !== null) {
// This callback now depends on the 'theme' prop
console.log(`Setting theme attribute to: ${theme}`);
node.setAttribute('data-theme', theme);
}
}, [theme]); // <-- Add 'theme' to the dependency array
return (
<div>
<p>Current Theme: {theme}</p>
<div ref={themedRefCallback}>This element's theme will update.</div>
{/* ... imagine a button here to change the parent's theme ... */}
</div>
);
}
ãã®äŸã§ã¯ãuseCallbackã®äŸåé¢ä¿é
åã«themeã远å ããŸãããããã¯ã次ãæå³ããŸãïŒ
- æ°ãã
themedRefCallback颿°ã¯ãthemeããããã£ã倿Žãããå Žåã«ã®ã¿äœæãããŸãã themeããããã£ã倿ŽããããšãReactã¯æ°ãã颿°ã€ã³ã¹ã¿ã³ã¹ãæ€åºããrefã³ãŒã«ããã¯ãåå®è¡ããŸãïŒæåã¯nullã§ã次ã«èŠçŽ ã§ïŒã- ããã«ããã广ïŒ`data-theme`屿§ã®èšå®ïŒãæŽæ°ããã
themeå€ã§åå®è¡ãããŸãã
ããã¯æ£ããæå³ãããåäœã§ããäŸåé¢ä¿ã倿Žããããšãã«refããžãã¯ãåããªã¬ãŒããããã«Reactã«æç€ºçã«æç€ºããªãããé¢ä¿ã®ãªãç¶æ ã®æŽæ°ã§å®è¡ãããªãããã«ããŸãã
ãµãŒãããŒãã£ã©ã€ãã©ãªãšã®çµ±å
ã³ãŒã«ããã¯refsã®æã匷åãªäœ¿çšäŸã®1ã€ã¯ãDOMããŒãã«ã¢ã¿ããããå¿ èŠããããµãŒãããŒãã£ã©ã€ãã©ãªã®ã€ã³ã¹ã¿ã³ã¹ãåæåããã³ç Žæ£ããããšã§ãããã®ãã¿ãŒã³ã¯ãã³ãŒã«ããã¯ã®ããŠã³ã/ã¢ã³ããŠã³ãã®æ§è³ªãå®å šã«æŽ»çšããŸãã
ãã£ãŒãã©ã€ãã©ãªããããã©ã€ãã©ãªãªã©ã®ã©ã€ãã©ãªã管çããããã®å ç¢ãªãã¿ãŒã³ã次ã«ç€ºããŸãïŒ
import React, { useRef, useCallback, useEffect } from 'react';
import SomeChartingLibrary from 'some-charting-library';
function ChartComponent({ data }) {
// Use a ref to hold the library instance, not the DOM node
const chartInstance = useRef(null);
const chartContainerRef = useCallback(node => {
// The node is null when the component unmounts
if (node === null) {
if (chartInstance.current) {
console.log('Cleaning up chart instance...');
chartInstance.current.destroy(); // Cleanup method from the library
chartInstance.current = null;
}
return;
}
// The node exists, so we can initialize our chart
console.log('Initializing chart instance...');
const chart = new SomeChartingLibrary(node, {
// Configuration options
data: data,
});
chartInstance.current = chart;
}, [data]); // Re-create the chart if the data prop changes
return <div className="chart-container" ref={chartContainerRef} style={{ height: '400px' }} />;
}
ãã®ãã¿ãŒã³ã¯éåžžã«ã¯ãªãŒã³ã§ãå埩åããããŸãïŒ
- åæåïŒ`div`ãããŠã³ãããããšãã³ãŒã«ããã¯ã¯`node`ãåãåããŸãããã£ãŒãã©ã€ãã©ãªã®æ°ããã€ã³ã¹ã¿ã³ã¹ãäœæãã`chartInstance.current`ã«æ ŒçŽããŸãã
- ã¯ãªãŒã³ã¢ããïŒã³ã³ããŒãã³ããã¢ã³ããŠã³ããããïŒãŸãã¯`data`ã倿Žãããåå®è¡ãããªã¬ãŒãããïŒãšãã³ãŒã«ããã¯ã¯æåã«`null`ã§åŒã³åºãããŸããã³ãŒãã¯ãã£ãŒãã€ã³ã¹ã¿ã³ã¹ãååšãããã©ããã確èªããååšããå Žåã¯ããã®`destroy()`ã¡ãœãããåŒã³åºããŠãã¡ã¢ãªãªãŒã¯ãé²ããŸãã
- æŽæ°ïŒäŸåé¢ä¿é åã«`data`ãå«ããããšã§ããã£ãŒãã®ããŒã¿ãæ ¹æ¬çã«å€æŽããå¿ èŠãããå Žåããã£ãŒãå šäœãã¯ãªãŒã³ã«ç Žæ£ãããæ°ããããŒã¿ã§ååæåãããããã«ããŸããåçŽãªããŒã¿æŽæ°ã®å Žåãã©ã€ãã©ãªã¯`update()`ã¡ãœãããæäŸããå ŽåããããŸããããã¯ãå¥ã®`useEffect`ã§åŠçã§ããŸãã
ããã©ãŒãã³ã¹ã®æ¯èŒïŒæé©åã¯*æ¬åœã«*ãã€éèŠã§ããïŒ
å®çšçãªèãæ¹ã§ããã©ãŒãã³ã¹ã«åãçµãããšãéèŠã§ãããã¹ãŠã®refã³ãŒã«ããã¯ã`useCallback`ã§ã©ããããããšã¯è¯ãç¿æ £ã§ãããå®éã®ããã©ãŒãã³ã¹ãžã®åœ±é¿ã¯ãã³ãŒã«ããã¯å ã§è¡ãããäœæ¥ã«ãã£ãŠå€§ããç°ãªããŸãã
ç¡èŠã§ãã圱é¿ã®ã·ããªãª
ã³ãŒã«ããã¯ãåçŽãªå€æ°ã®ä»£å ¥ã®ã¿ãå®è¡ããå Žåãã¬ã³ããªã³ã°ããšã«æ°ãã颿°ãäœæãããªãŒããŒãããã¯ãããããã§ããææ°ã®JavaScriptãšã³ãžã³ã¯ã颿°ã®äœæãšã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãéåžžã«é«éã§ãã
äŸïŒ ref={(node) => (myRef.current = node)}
ãã®ãããªå Žåãæè¡çã«ã¯æé©ã§ã¯ãããŸããããå®éã®ã¢ããªã±ãŒã·ã§ã³ã§ããã©ãŒãã³ã¹ã®éããæž¬å®ã§ããå¯èœæ§ã¯äœãã§ããææå°æ©ãªæé©åã®çœ ã«ã¯ãŸããªãã§ãã ããã
倧ããªåœ±é¿ã®ã·ããªãª
refã³ãŒã«ããã¯ã次ã®ãããããå®è¡ããå Žåã¯ãåžžã«useCallbackã䜿çšããå¿
èŠããããŸãïŒ
- DOMæäœïŒã¯ã©ã¹ã®çŽæ¥çãªè¿œå ãŸãã¯åé€ã屿§ã®èšå®ããŸãã¯èŠçŽ ãµã€ãºã®æž¬å®ïŒã¬ã€ã¢ãŠããªãããŒãããªã¬ãŒããå¯èœæ§ããããŸãïŒã
- ã€ãã³ããªã¹ããŒïŒ`addEventListener`ãš`removeEventListener`ã®åŒã³åºããããããã¹ãŠã®ã¬ã³ããªã³ã°ã§çºçãããããšã¯ããã°ãšããã©ãŒãã³ã¹ã®åé¡ã確å®ã«çºçãããæ¹æ³ã§ãã
- ã©ã€ãã©ãªã®ã€ã³ã¹ã¿ã³ã¹åïŒãã£ãŒãã®äŸã§ç€ºããããã«ãè€éãªãªããžã§ã¯ãã®åæåãšç Žæ£ã¯ã³ã¹ããããããŸãã
- ãããã¯ãŒã¯ãªã¯ãšã¹ãïŒDOMèŠçŽ ã®ååšã«åºã¥ããŠAPIåŒã³åºããè¡ããŸãã
- ã¡ã¢åãããåãžã®Refsã®æž¡ãïŒ
React.memoã§ã©ãããããåã³ã³ããŒãã³ãã«refã³ãŒã«ããã¯ãpropãšããŠæž¡ããšãäžå®å®ãªã€ã³ã©ã€ã³é¢æ°ãã¡ã¢åãè§£é€ããåãäžå¿ èŠã«åã¬ã³ããªã³ã°ãããŸãã
è¯ãçµéšåïŒrefã³ãŒã«ããã¯ã«åçŽãªä»£å
¥ã1ã€ä»¥äžå«ãå Žåã¯ãuseCallbackã§ã¡ã¢åããŸãã
çµè«ïŒäºæž¬å¯èœã§ããã©ãŒãã³ã¹ã®é«ãã³ãŒãã®äœæ
Reactã®refã³ãŒã«ããã¯ã¯ãDOMããŒããšã³ã³ããŒãã³ãã€ã³ã¹ã¿ã³ã¹ããã现ããå¶åŸ¡ã§ãã匷åãªããŒã«ã§ãããã®ã©ã€ããµã€ã¯ã«ãç¹ã«ã¯ãªãŒã³ã¢ããäžã®æå³çãª`null`åŒã³åºããçè§£ããããšãã广çã«äœ¿çšããããã®éµã§ãã
refããããã£ã«ã€ã³ã©ã€ã³é¢æ°ã䜿çšãããšããäžè¬çãªã¢ã³ããã¿ãŒã³ã¯ããã¹ãŠã®ã¬ã³ããªã³ã°ã§äžèŠã§æœåšçã«ã³ã¹ãã®ãããåå®è¡ã«ã€ãªããããšãåŠã³ãŸããã解決çã¯ããšã¬ã¬ã³ãã§æ
£çšçãªReactã§ãïŒuseCallbackããã¯ã䜿çšããŠã³ãŒã«ããã¯é¢æ°ãå®å®åããŸãã
ãã®ãã¿ãŒã³ããã¹ã¿ãŒããããšã§ã次ã®ããšãå¯èœã«ãªããŸãïŒ
- ããã©ãŒãã³ã¹ã®ããã«ããã¯ã鲿¢ïŒãã¹ãŠã®ç¶æ 倿Žã§ã³ã¹ãã®ãããã»ããã¢ãããšç Žæ£ã®ããžãã¯ãåé¿ããŸãã
- ãã°ã®æé€ïŒã€ãã³ããªã¹ããŒãšã©ã€ãã©ãªã€ã³ã¹ã¿ã³ã¹ããéè€ãã¡ã¢ãªãªãŒã¯ãªãã«ã¯ãªãŒã³ã«ç®¡çãããããã«ããŸãã
- äºæž¬å¯èœãªã³ãŒãã®äœæïŒã³ã³ããŒãã³ããããŠã³ããã¢ã³ããŠã³ãããããšãããŸãã¯ç¹å®ã®äŸåé¢ä¿ã倿Žããããšãã«ã®ã¿ãæåŸ ã©ããã«åäœããrefããžãã¯ãæã€ã³ã³ããŒãã³ããäœæããŸãã
次ã«ãè€éãªåé¡ã解決ããããã«refã䜿çšããå Žåã¯ãã¡ã¢åãããã³ãŒã«ããã¯ã®åãæãåºããŠãã ãããããã¯ãã³ãŒãã®å°ããªå€æŽã§ãããReactã¢ããªã±ãŒã·ã§ã³ã®å質ãšããã©ãŒãã³ã¹ã«å€§ããªéãããããããäžçäžã®ãŠãŒã¶ãŒã«ãšã£ãŠããè¯ããšã¯ã¹ããªãšã³ã¹ã«è²¢ç®ããŸãã