Reactã®useDeferredValueããã¯ã培åºè§£èª¬ãéèŠåºŠã®äœãæŽæ°ãé å»¶ãããŠãŒã¶ãŒæäœãåªå ããããšã§ããã©ãŒãã³ã¹ãæé©åããæ¹æ³ããå®è·µçãªäŸãšãã¹ããã©ã¯ãã£ã¹ã亀ããŠæ¢ããŸãã
React useDeferredValueïŒããã©ãŒãã³ã¹ã®æé©åãšåªå é äœä»ãããã¹ã¿ãŒãã
çµ¶ããé²åããããã³ããšã³ãéçºã®äžçã«ãããŠãããã©ãŒãã³ã¹ã¯æãéèŠã§ãããŠãŒã¶ãŒã¯ã¬ã¹ãã³ã·ãã§æ»ãããªã€ã³ã¿ãŒãã§ãŒã¹ãæåŸ
ããŠãããããããªé
å»¶ã§ããŠãŒã¶ãŒäœéšã«æªåœ±é¿ãåãŒãå¯èœæ§ããããŸãããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãæ§ç¯ããããã®äž»èŠãªJavaScriptã©ã€ãã©ãªã§ããReactã¯ãããã©ãŒãã³ã¹ã®ããã«ããã¯ã«å¯ŸåŠããããã®æ§ã
ãªããŒã«ãæäŸããŠããŸãããã®äžã§ããuseDeferredValueããã¯ã¯ãã¬ã³ããªã³ã°ãæé©åãããŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ãåªå
ããããã®åŒ·åãªã¡ã«ããºã ãšããŠéç«ã£ãŠããŸãããã®å
æ¬çãªã¬ã€ãã§ã¯ãuseDeferredValueã®è€éãªä»çµã¿ãæ¢ããReactã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãåäžãããããã«å¹æçã«äœ¿çšããæ¹æ³ã解説ããŸãã
åé¡ã®çè§£ïŒåæçãªæŽæ°ã®ã³ã¹ã
Reactã®ããã©ã«ãã®ã¬ã³ããªã³ã°åäœã¯åæçã§ããstateã倿ŽããããšãReactã¯å³åº§ã«é¢é£ããã³ã³ããŒãã³ããåã¬ã³ããªã³ã°ããŸããããã«ããUIãã¢ããªã±ãŒã·ã§ã³ã®ç¶æ ãæ£ç¢ºã«åæ ããããšãä¿èšŒãããŸãããèšç®ã³ã¹ãã®é«ãæäœãé »ç¹ãªæŽæ°ãæ±ãå Žåã«ã¯åé¡ãšãªãå¯èœæ§ããããŸããäŸãã°ãããŒã¹ãããŒã¯ããšã«çµæãæŽæ°ãããæ€çŽ¢ããŒãæ³åããŠã¿ãŠãã ãããæ€çŽ¢ã¢ã«ãŽãªãºã ãè€éã§ãã£ãããçµæã»ããã倧ããå ŽåãåæŽæ°ãé«ã³ã¹ããªåã¬ã³ããªã³ã°ãåŒãèµ·ãããé¡èãªã©ã°ããã©ã¹ãã¬ãŒã·ã§ã³ã®ããŸããŠãŒã¶ãŒäœéšã«ã€ãªããå¯èœæ§ããããŸãã
ããã§useDeferredValueã圹ç«ã¡ãŸããããã«ãããUIã®éèŠã§ãªãéšåãžã®æŽæ°ãé
å»¶ãããããšãã§ãããŠãŒã¶ãŒã®äž»èŠãªã€ã³ã¿ã©ã¯ã·ã§ã³ãã¹ã ãŒãºã§ã¬ã¹ãã³ã·ãã§ããç¶ããããšãä¿èšŒããŸãã
useDeferredValueã®ç޹ä»ïŒã¬ã¹ãã³ã¹æ§åäžã®ããã®æŽæ°ã®é å»¶
React 18ã§å°å
¥ãããuseDeferredValueããã¯ã¯ãå€ãå
¥åãšããŠåãåãããã®å€ã®æ°ããé
å»¶ããŒãžã§ã³ãè¿ããŸããéèŠãªã®ã¯ãReactãå
ã®é
å»¶ãããŠããªãå€ã«é¢é£ããæŽæ°ãåªå
ããUIããŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ã«è¿
éã«å¿çã§ããããã«ããäžæ¹ã§ãé
å»¶ãããå€ã«é¢é£ããæŽæ°ã¯ãã©ãŠã¶ã«äœè£ãã§ãããŸã§é
å»¶ããããšããç¹ã§ãã
ä»çµã¿ïŒç°¡åãªèª¬æ
ãã®ããã«èããŠã¿ãŠãã ãããåãæ å ±ã«2ã€ã®ããŒãžã§ã³ããããšããŸããé«åªå 床ããŒãžã§ã³ãšäœåªå 床ããŒãžã§ã³ã§ããReactã¯é«åªå 床ããŒãžã§ã³ããªã¢ã«ã¿ã€ã ã§ææ°ã®ç¶æ ã«ä¿ã€ããšã«éäžããã¹ã ãŒãºã§ã¬ã¹ãã³ã·ããªãŠãŒã¶ãŒäœéšãä¿èšŒããŸããäœåªå 床ããŒãžã§ã³ã¯ããã©ãŠã¶ãå¿ãããªããšãã«ããã¯ã°ã©ãŠã³ãã§æŽæ°ãããŸããããã«ããããŠãŒã¶ãŒã®ã€ã³ã¿ã©ã¯ã·ã§ã³ããããã¯ããããšãªããäžæçã«å°ãå€ãããŒãžã§ã³ã®æ å ±ã衚瀺ããããšãã§ããŸãã
å®è·µäŸïŒuseDeferredValueã®å®è£
useDeferredValueã®äœ¿ãæ¹ããããã€ãã®å®è·µçãªäŸã§èª¬æããŸãããã
äŸ1ïŒæ€çŽ¢ããŒã®æé©å
ãŠãŒã¶ãŒå
¥åã«åºã¥ããŠã¢ã€ãã ã®ãªã¹ãããã£ã«ã¿ãªã³ã°ããæ€çŽ¢ããŒã³ã³ããŒãã³ããèããŠã¿ãŸããããuseDeferredValueã䜿çšããªãå Žåããã¹ãŠã®ããŒã¹ãããŒã¯ãåã¬ã³ããªã³ã°ãåŒãèµ·ãããã©ã°ã®åå ãšãªãå¯èœæ§ããããŸãã以äžã¯useDeferredValueã䜿çšããŠãã®ã³ã³ããŒãã³ããæé©åããæ¹æ³ã§ãïŒ
import React, { useState, useDeferredValue } from 'react';
function SearchBar({ items }) {
const [searchTerm, setSearchTerm] = useState('');
const deferredSearchTerm = useDeferredValue(searchTerm);
const filteredItems = items.filter(item =>
item.toLowerCase().includes(deferredSearchTerm.toLowerCase())
);
const handleChange = (event) => {
setSearchTerm(event.target.value);
};
return (
<div>
<input type="text" value={searchTerm} onChange={handleChange} placeholder="Search..." />
<ul>
{filteredItems.map(item => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
export default SearchBar;
ãã®äŸã§ã¯ãsearchTermã¯å³æã®ãŠãŒã¶ãŒå
¥åã衚ããdeferredSearchTermã¯ãã®é
å»¶ããŒãžã§ã³ã§ãããã£ã«ã¿ãªã³ã°ããžãã¯ã¯deferredSearchTermã䜿çšããŠå®è¡ãããããããã£ã«ã¿ãªã³ã°åŠçãèšç®éçŽçã§ãã£ãŠãå
¥åãã£ãŒã«ãã®å¿çæ§ã¯ç¶æãããŸãããŠãŒã¶ãŒã¯å
¥åãã£ãŒã«ãã§å³æã®ãã£ãŒãããã¯ãäœéšãããã£ã«ã¿ãªã³ã°ãããã¢ã€ãã ã®ãªã¹ãã¯ãã©ãŠã¶ã«å©çšå¯èœãªãªãœãŒã¹ããããšãã«å°ãé
ããŠæŽæ°ãããŸãã
äŸ2ïŒãªã¢ã«ã¿ã€ã ããŒã¿è¡šç€ºã®åŒ·å
é »ç¹ã«æŽæ°ããããªã¢ã«ã¿ã€ã ããŒã¿ã衚瀺ããããšãæ³åããŠã¿ãŠãã ãããæŽæ°ã®ãã³ã«è¡šç€ºå
šäœãæŽæ°ãããšãããã©ãŒãã³ã¹ã®åé¡ã«ã€ãªããå¯èœæ§ããããŸããuseDeferredValueã䜿çšããŠã衚瀺ã®éèŠåºŠã®äœãéšåãžã®æŽæ°ãé
å»¶ãããããšãã§ããŸãã
import React, { useState, useEffect, useDeferredValue } from 'react';
function RealTimeDataDisplay() {
const [data, setData] = useState([]);
const deferredData = useDeferredValue(data);
useEffect(() => {
// Simulate real-time data updates
const intervalId = setInterval(() => {
setData(prevData => [...prevData, Math.random()]);
}, 100);
return () => clearInterval(intervalId);
}, []);
return (
<div>
<h2>Real-time Data
<ul>
{deferredData.map((item, index) => (
<li key={index}>{item.toFixed(2)}</li>
))}
</ul>
</div>
);
}
export default RealTimeDataDisplay;
ãã®ã·ããªãªã§ã¯ãdataã¹ããŒãã¯ãªã¢ã«ã¿ã€ã ããŒã¿ãã·ãã¥ã¬ãŒãããŠé »ç¹ã«æŽæ°ãããŸããdeferredData倿°ã«ããããªã¹ãã¯ãããã«é
ãããŒã¹ã§æŽæ°ãããUIãå¿çäžèœã«ãªãã®ãé²ããŸããããã«ãããããŒã¿è¡šç€ºãããã¯ã°ã©ãŠã³ãã§æŽæ°ãããŠããéã§ããã¢ããªã±ãŒã·ã§ã³ã®ä»ã®éšåã察話å¯èœãªç¶æ
ãç¶æã§ããŸãã
äŸ3ïŒè€éãªããžã¥ã¢ã©ã€ãŒãŒã·ã§ã³ã®æé©å
å€§èŠæš¡ãªãã£ãŒããã°ã©ããªã©ã®è€éãªããžã¥ã¢ã©ã€ãŒãŒã·ã§ã³ãã¬ã³ããªã³ã°ããã·ããªãªãèããŠã¿ãŸããããããŒã¿ã倿Žããããã³ã«ãã®ããžã¥ã¢ã©ã€ãŒãŒã·ã§ã³ãæŽæ°ããã®ã¯ãèšç®ã³ã¹ããé«ããªãå¯èœæ§ããããŸãã`useDeferredValue`ã䜿çšããããšã§ãåæã¬ã³ããªã³ã°ãåªå ããåŸç¶ã®æŽæ°ãé å»¶ãããŠå¿çæ§ãåäžãããããšãã§ããŸãã
import React, { useState, useEffect, useDeferredValue } from 'react';
import { Chart } from 'chart.js/auto'; // Or your preferred charting library
function ComplexVisualization() {
const [chartData, setChartData] = useState({});
const deferredChartData = useDeferredValue(chartData);
const chartRef = React.useRef(null);
useEffect(() => {
// Simulate fetching chart data
const fetchData = async () => {
// Replace with your actual data fetching logic
const newData = {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
}]
};
setChartData(newData);
};
fetchData();
}, []);
useEffect(() => {
if (Object.keys(deferredChartData).length > 0) {
if (chartRef.current) {
chartRef.current.destroy(); // Destroy previous chart if it exists
}
const chartCanvas = document.getElementById('myChart');
if (chartCanvas) {
chartRef.current = new Chart(chartCanvas, {
type: 'bar',
data: deferredChartData,
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
}
}
}, [deferredChartData]);
return (
<div>
<canvas id="myChart" width="400" height="200"></canvas>
</div>
);
}
export default ComplexVisualization;
ãã®äŸã§ã¯ããã£ãŒãã©ã€ãã©ãªïŒChart.jsïŒã䜿çšããŠæ£ã°ã©ããã¬ã³ããªã³ã°ããŸãã`deferredChartData`ã䜿çšããŠãã£ãŒããæŽæ°ããããšã§ãåæã¬ã³ããªã³ã°ãè¿ éã«å®äºããåŸç¶ã®æŽæ°ã¯ãã©ãŠã¶ã«å©çšå¯èœãªãªãœãŒã¹ããããŸã§é å»¶ãããŸãããã®ã¢ãããŒãã¯ãå€§èŠæš¡ãªããŒã¿ã»ãããè€éãªãã£ãŒãæ§æãæ±ãå Žåã«ç¹ã«åœ¹ç«ã¡ãŸãã
useDeferredValueã䜿çšããããã®ãã¹ããã©ã¯ãã£ã¹
useDeferredValueã广çã«æŽ»çšããããã«ã以äžã®ãã¹ããã©ã¯ãã£ã¹ãèæ
®ããŠãã ããïŒ
- ããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ããïŒ
useDeferredValueãå®è£ ããåã«ãããã©ãŒãã³ã¹åé¡ãåŒãèµ·ãããŠããç¹å®ã®ã³ã³ããŒãã³ããæäœãç¹å®ããŸããReact Profilerããã©ãŠã¶ã®éçºè ããŒã«ã䜿çšããŠããã«ããã¯ãçªãæ¢ããŸãã - éèŠã§ãªãæŽæ°ã察象ã«ããïŒ å³æã®ãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ã«äžå¯æ¬ ã§ãªãUIéšåãžã®æŽæ°ãé å»¶ãããããšã«çŠç¹ãåœãŠãŸããäŸãã°ãäºæ¬¡çãªæ å ±è¡šç€ºãéèŠã§ãªãèŠèŠèŠçŽ ãžã®æŽæ°ã®é å»¶ãæ€èšããŸãã
- ããã©ãŒãã³ã¹ãç£èŠããïŒ
useDeferredValueãå®è£ ããåŸã倿ŽãæåŸ ããã广ããããããŠãããã確èªããããã«ã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãç£èŠããŸããããã©ãŒãã³ã¹ã¡ããªã¯ã¹ã䜿çšããŠãå¿çæ§ããã¬ãŒã ã¬ãŒãã®æ¹åã远跡ããŸãã - 䜿ããããé¿ããïŒ
useDeferredValueã¯åŒ·åãªããŒã«ã§ããã䜿ãããã¯é¿ããŠãã ãããããŸãã«ãå€ãã®æŽæ°ãé å»¶ããããšãå¿çæ§ãæ¬ ããŠãããšèªèãããå¯èœæ§ããããŸããæã倧ããªããã©ãŒãã³ã¹äžã®å©ç¹ãåŸãããé åã«ã®ã¿ãæ éã«äœ¿çšããŠãã ããã - ä»£æ¿æ¡ãæ€èšããïŒ
useDeferredValueã«é Œãåã«ãã¡ã¢åïŒReact.memoïŒãã³ãŒãåå²ãªã©ã®ä»ã®æé©åææ³ãæ¢ããŸãããããã®ææ³ã¯ãç¹å®ã®ããã©ãŒãã³ã¹åé¡ã«å¯ŸããŠããå¹ççãªè§£æ±ºçãæäŸããå¯èœæ§ããããŸãã
useDeferredValue vs. useTransitionïŒé©åãªããŒã«ã®éžæ
React 18ã§ã¯ãæŽæ°ã管çããŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ãåªå
ããããã®å¥ã®ã¡ã«ããºã ãæäŸããuseTransitionããã¯ãå°å
¥ãããŸãããuseDeferredValueãšuseTransitionã¯ã©ã¡ããããã©ãŒãã³ã¹ã®åäžãç®æããŠããŸãããç®çãç°ãªããŸãã
useDeferredValueã¯äž»ã«ç¹å®ã®å€ãžã®æŽæ°ãé
å»¶ãããããã«äœ¿çšãããé
å»¶ãããå€ãããã¯ã°ã©ãŠã³ãã§æŽæ°ãããŠããéãUIã®å¿çæ§ãç¶æããŸãã峿ã®ãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ãåªå
ããUIã®éèŠã§ãªãéšåãžã®ããããªé
å»¶æŽæ°ãåãå
¥ããã·ããªãªã«é©ããŠããŸãã
äžæ¹ãuseTransitionã¯ãç¹å®ã®stateæŽæ°ããã©ã³ãžã·ã§ã³ãšããŠããŒã¯ããããã«äœ¿çšãããŸããReactã¯ãããã®æŽæ°ãåªå
ããUIããããã¯ããããšãªãå®äºããããšè©Šã¿ãŸããuseTransitionã¯ãèšç®ã³ã¹ããé«ãå Žåã§ããstateæŽæ°ãã¹ã ãŒãºã«ããã€ãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ãäžæããããšãªãå®è¡ãããããšãä¿èšŒãããã·ããªãªã§åœ¹ç«ã¡ãŸãã
以äžã«ãäž»ãªéãããŸãšãã衚ã瀺ããŸãïŒ
| æ©èœ | useDeferredValue | useTransition |
|---|---|---|
| äž»ãªç®ç | ç¹å®ã®å€ãžã®æŽæ°ãé å»¶ããã | stateæŽæ°ããã©ã³ãžã·ã§ã³ãšããŠããŒã¯ãã |
| ãŠãŒã¹ã±ãŒã¹ | æ€çŽ¢ããŒããªã¢ã«ã¿ã€ã ããŒã¿è¡šç€ºã®æé©å | ã«ãŒãé·ç§»ãè€éãªstateæŽæ°ã®æé©å |
| ã¡ã«ããºã | ãã©ãŠã¶ã«äœè£ãã§ãããŸã§æŽæ°ãé å»¶ããã | æŽæ°ãåªå ããUIããããã¯ããã«å®äºã詊ã¿ã |
äžè¬çã«ãå€ãå¯èœæ§ã®ããããŒã¿ã衚瀺ãã€ã€UIã®å¿çæ§ãä¿ã¡ããå Žåã¯useDeferredValueã䜿çšããŸããUIã®å¿çæ§ãä¿ã¡ã€ã€ãæ°ããããŒã¿ãæºåã§ãããŸã§ããŒã¿ã®è¡šç€ºãé
å»¶ããããå Žåã¯useTransitionã䜿çšããŸãã
ã°ããŒãã«ãªèæ ®äºé ïŒå€æ§ãªç°å¢ãžã®é©å¿
ã°ããŒãã«ãªãªãŒãã£ãšã³ã¹åãã®ã¢ããªã±ãŒã·ã§ã³ãéçºããéã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã䜿çšããã倿§ãªç°å¢ãèæ
®ããããšãäžå¯æ¬ ã§ãããããã¯ãŒã¯ã®é
å»¶ãããã€ã¹ã®æ§èœããŠãŒã¶ãŒã®æåŸ
ã¯ãå°åã«ãã£ãŠå€§ããç°ãªãå ŽåããããŸãã以äžã¯ãã°ããŒãã«ãªæèã§useDeferredValueã䜿çšããéã®èæ
®äºé
ã§ãïŒ
- ãããã¯ãŒã¯ç¶æ³ïŒ ãããã¯ãŒã¯æ¥ç¶ãæªãå°åã§ã¯ã
useDeferredValueã®å©ç¹ãããã«é¡èã«ãªãå¯èœæ§ããããŸããæŽæ°ãé å»¶ãããããšã§ãããŒã¿è»¢éãé ãããŸãã¯ä¿¡é Œæ§ããªãå Žåã§ããã¬ã¹ãã³ã·ããªUIãç¶æããã®ã«åœ¹ç«ã¡ãŸãã - ããã€ã¹ã®æ§èœïŒ äžéšã®å°åã®ãŠãŒã¶ãŒã¯ãå€ããŸãã¯æ§èœã®äœãããã€ã¹ã䜿çšããŠããå ŽåããããŸãã
useDeferredValueã¯ãCPUãGPUãžã®è² è·ãæžããããšã§ããããã®ããã€ã¹ã§ã®ããã©ãŒãã³ã¹åäžã«åœ¹ç«ã¡ãŸãã - ãŠãŒã¶ãŒã®æåŸ ïŒ ããã©ãŒãã³ã¹ãå¿çæ§ã«é¢ãããŠãŒã¶ãŒã®æåŸ ã¯ãæåã«ãã£ãŠç°ãªãå ŽåããããŸããã¿ãŒã²ãããªãŒãã£ãšã³ã¹ã®æåŸ ãçè§£ããããã«å¿ããŠã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ã調æŽããããšãéèŠã§ãã
- ããŒã«ã©ã€ãŒãŒã·ã§ã³ïŒ æŽæ°ãé å»¶ãããéã¯ãããŒã«ã©ã€ãŒãŒã·ã§ã³ã«é¢ããèæ ®äºé ã«æ³šæããŠãã ãããé å»¶ãããã³ã³ãã³ããé©åã«ããŒã«ã©ã€ãºãããç°ãªãèšèªãå°åéã§ãŠãŒã¶ãŒäœéšãäžè²«ããŠããããšã確èªããŠãã ãããäŸãã°ãæ€çŽ¢çµæã®è¡šç€ºãé å»¶ãããå ŽåãçµæããŠãŒã¶ãŒã®ãã±ãŒã«ã«åãããŠé©åã«ç¿»èš³ã»ãã©ãŒããããããŠããããšã確èªããŸãã
ãããã®èŠå ãèæ ®ããããšã§ãã¢ããªã±ãŒã·ã§ã³ãæé©ã«åäœããäžçäžã®ãŠãŒã¶ãŒã«ããžãã£ããªãŠãŒã¶ãŒäœéšãæäŸããããšãä¿èšŒã§ããŸãã
çµè«ïŒæŠç¥çãªé å»¶ã«ããReactããã©ãŒãã³ã¹ã®åŒ·å
useDeferredValueã¯Reactéçºè
ã®ããŒã«ããããžã®äŸ¡å€ãã远å ã§ãããããã©ãŒãã³ã¹ãæé©åãããŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ã广çã«åªå
ãããããšãã§ããŸããUIã®éèŠã§ãªãéšåãžã®æŽæ°ãæŠç¥çã«é
å»¶ãããããšã§ãããã¬ã¹ãã³ã·ãã§æ»ãããªã¢ããªã±ãŒã·ã§ã³ãäœæã§ããŸããuseDeferredValueã®ãã¥ã¢ã³ã¹ãçè§£ãããã¹ããã©ã¯ãã£ã¹ãé©çšããã°ããŒãã«ãªèŠå ãèæ
®ããããšã§ãäžçäžã®ãªãŒãã£ãšã³ã¹ã«åè¶ãããŠãŒã¶ãŒäœéšãæäŸã§ããããã«ãªããŸããReactãé²åãç¶ããäžã§ããããã®ããã©ãŒãã³ã¹æé©åæè¡ãç¿åŸããããšã¯ãé«å質ã§é«æ§èœãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã«äžå¯æ¬ ã§ãã