应用场景对比
-
useMemo:
-
复杂计算的缓存:
- 例如,在一个数据可视化组件中,需要对大量的数据进行复杂的统计计算,如计算平均值、标准差等。
import React, { useState, useMemo } from 'react'; const DataVisualizationComponent = () => { const [data, setData] = useState([1, 2, 3, 4, 5]); // 计算平均值并缓存结果 const average = useMemo(() => { const sum = data.reduce((acc, val) => acc + val, 0); return sum / data.length; }, [data]); return ( <div> <p>数据平均值: {average}</p> </div> ); }; export default DataVisualizationComponent;
- 解释:每次
data
发生变化时,useMemo
会重新计算平均值;如果data
不变,即使组件因为其他原因重新渲染,也会直接使用缓存的平均值,避免了重复计算。
-
避免数据处理的重复执行:
- 假设要对一个文本字符串进行复杂的格式化操作,如将一段包含HTML标签的文本转换为纯文本并进行单词计数。
import React, { useState, useMemo } from 'react'; const TextProcessingComponent = () => { const [text, setText] = useState("<p>Hello, World!</p>"); // 缓存格式化后的文本和单词计数结果 const [formattedText, wordCount] = useMemo(() => { const plainText = text.replace(/<[^>]*>/g, ""); const words = plainText.split(" ").length; return [plainText, words]; }, [text]); return ( <div> <p>格式化后的文本: {formattedText}</p> <p>单词计数: {wordCount}</p> </div> ); }; export default TextProcessingComponent;
- 解释:
useMemo
确保只有当text
发生变化时,才会重新进行文本格式化和单词计数操作。
-
复杂计算的缓存:
-
useCallback:
-
优化子组件渲染(传递回调函数):
- 考虑一个包含列表和删除按钮的组件,点击删除按钮会调用一个回调函数来删除列表中的某个元素。
import React, { useState, useCallback } from 'react'; const ParentListComponent = () => { const [list, setList] = useState([1, 2, 3]); // 记忆化删除函数 const handleDelete = useCallback((index) => { const newList = [...list]; newList.splice(index, 1); setList(newList); }, [list]); return ( <div> {list.map((item, index) => ( <ChildListItem key={item} item={item} onDelete={handleDelete(index)} /> ))} </div> ); }; const ChildListItem = ({ item, onDelete }) => { return ( <div> <p>{item}</p> <button onClick={onDelete}>删除</button> </div> ); }; export default ParentListComponent;
- 解释:
useCallback
用于缓存handleDelete
函数。只有当list
发生变化时,handleDelete
函数才会重新创建。这样,在ParentListComponent
重新渲染时,如果list
没有变化,传递给ChildListItem
的onDelete
函数引用不会改变,从而避免了ChildListItem
因为函数引用改变而不必要地重新渲染。
-
事件处理函数的优化:
- 例如,在一个游戏组件中有多个按钮,每个按钮都有自己的点击事件处理函数,这些函数可能会根据游戏状态(如得分、关卡等)进行一些操作。
import React, { useState, useCallback } from 'react'; const GameComponent = () => { const [score, setScore] = useState(0); const [level, setLevel] = useState(1); // 记忆化加分事件处理函数 const handleAddScore = useCallback(() => { setScore(score + 10); }, [score]); // 记忆化升级事件处理函数 const handleLevelUp = useCallback(() => { setLevel(level + 1); }, [level]); return ( <div> <button onClick={handleAddScore}>加分</button> <button onClick={handleLevelUp}>升级</button> </div> ); }; export default GameComponent;
- 解释:
useCallback
确保每个事件处理函数只有在其依赖的游戏状态(score
或level
)发生变化时才会重新创建。这有助于在游戏状态更新时,只重新渲染与状态变化相关的部分,提高性能。
-
优化子组件渲染(传递回调函数):