react 组件应用

时间:2024-11-10 17:17:05

应用场景对比

  • 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没有变化,传递给ChildListItemonDelete函数引用不会改变,从而避免了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确保每个事件处理函数只有在其依赖的游戏状态(scorelevel)发生变化时才会重新创建。这有助于在游戏状态更新时,只重新渲染与状态变化相关的部分,提高性能。