亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

React?useCallback使用方法詳解

 更新時間:2025年01月21日 08:21:42   作者:前端涂涂  
useCallback?是?React?的一個?Hook,用于記憶函數(shù)定義,避免在每次渲染時創(chuàng)建新的函數(shù)實例,本文主要來介紹一下它的具體用法,需要的可以參考一下

1. useCallback 基礎(chǔ)概念

useCallback 是 React 的一個 Hook,用于記憶函數(shù)定義,避免在每次渲染時創(chuàng)建新的函數(shù)實例。它在需要將回調(diào)函數(shù)傳遞給經(jīng)過優(yōu)化的子組件時特別有用。 當(dāng)state變化的時候引起組件重新渲染執(zhí)行會導(dǎo)致某個方法被反復(fù)創(chuàng)建增加內(nèi)存負(fù)擔(dān),這個時候可以使用useCallback將該函數(shù)進(jìn)行緩存,只創(chuàng)建一次

1.1 基本語法

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b], // 依賴項數(shù)組
);

同樣的當(dāng)依賴項省略時組件重新渲染都會執(zhí)行,當(dāng)依賴項為空數(shù)組的時候只有組件初始化的時候會執(zhí)行一次,數(shù)組里有依賴項的時候依賴項發(fā)生變化的時候都會緩存一次

1.2 與普通函數(shù)的區(qū)別

function ParentComponent() {
  const [count, setCount] = useState(0);

  // ? 每次渲染都會創(chuàng)建新的函數(shù)實例
  const handleClick = () => {
    console.log('Clicked');
  };

  // ? 函數(shù)實例會被記憶,只在依賴項變化時更新
  const handleClickMemoized = useCallback(() => {
    console.log('Clicked');
  }, []); // 空依賴數(shù)組,函數(shù)永遠(yuǎn)不會改變

  return <ChildComponent onClick={handleClickMemoized} />;
}

2. useCallback 配合 React.memo 使用

2.1 基本示例

// 子組件使用 React.memo 優(yōu)化
const ChildComponent = React.memo(function ChildComponent({ onClick }) {
  console.log("ChildComponent rendered");
  return <button onClick={onClick}>Click me</button>;
});

// 父組件使用 useCallback
function ParentComponent() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState("");

  // 使用 useCallback 記憶回調(diào)函數(shù)
  const handleClick = useCallback(() => {
    setCount(c => c + 1);
  }, []); // 空依賴數(shù)組,因為不依賴任何值

  return (
    <div>
      <input value={text} onChange={e => setText(e.target.value)} />
      <p>Count: {count}</p>
      <ChildComponent onClick={handleClick} />
    </div>
  );
}

2.2 帶有依賴項的示例

function SearchComponent({ onSearch }) {
  const [searchTerm, setSearchTerm] = useState("");
  const [searchHistory, setSearchHistory] = useState([]);

  // 使用 useCallback 記憶搜索函數(shù)
  const handleSearch = useCallback(() => {
    if (searchTerm.trim()) {
      onSearch(searchTerm);
      setSearchHistory(prev => [...prev, searchTerm]);
    }
  }, [searchTerm, onSearch]); // 依賴 searchTerm 和 onSearch

  return (
    <div>
      <input
        value={searchTerm}
        onChange={e => setSearchTerm(e.target.value)}
      />
      <SearchButton onClick={handleSearch} />
      <SearchHistory items={searchHistory} />
    </div>
  );
}

// 優(yōu)化的子組件
const SearchButton = React.memo(function SearchButton({ onClick }) {
  console.log("SearchButton rendered");
  return <button onClick={onClick}>搜索</button>;
});

const SearchHistory = React.memo(function SearchHistory({ items }) {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
});

3. 實際應(yīng)用場景

3.1 表單處理

function ComplexForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  });

  // 記憶表單字段更新函數(shù)
  const handleFieldChange = useCallback((fieldName) => (event) => {
    setFormData(prev => ({
      ...prev,
      [fieldName]: event.target.value
    }));
  }, []); // 不需要依賴項,因為使用了函數(shù)式更新

  return (
    <form>
      <FormField
        label="Name"
        value={formData.name}
        onChange={handleFieldChange('name')}
      />
      <FormField
        label="Email"
        value={formData.email}
        onChange={handleFieldChange('email')}
      />
      <FormField
        label="Message"
        value={formData.message}
        onChange={handleFieldChange('message')}
      />
    </form>
  );
}

const FormField = React.memo(function FormField({ label, value, onChange }) {
  console.log(`${label} field rendered`);
  return (
    <div>
      <label>{label}</label>
      <input value={value} onChange={onChange} />
    </div>
  );
});

3.2 列表渲染優(yōu)化

function TodoList() {
  const [todos, setTodos] = useState([]);

  // 記憶添加任務(wù)函數(shù)
  const handleAdd = useCallback((text) => {
    setTodos(prev => [...prev, { id: Date.now(), text, completed: false }]);
  }, []);

  // 記憶切換完成狀態(tài)函數(shù)
  const handleToggle = useCallback((id) => {
    setTodos(prev =>
      prev.map(todo =>
        todo.id === id ? { ...todo, completed: !todo.completed } : todo
      )
    );
  }, []);

  // 記憶刪除函數(shù)
  const handleDelete = useCallback((id) => {
    setTodos(prev => prev.filter(todo => todo.id !== id));
  }, []);

  return (
    <div>
      <AddTodo onAdd={handleAdd} />
      {todos.map(todo => (
        <TodoItem
          key={todo.id}
          todo={todo}
          onToggle={handleToggle}
          onDelete={handleDelete}
        />
      ))}
    </div>
  );
}

const TodoItem = React.memo(function TodoItem({ todo, onToggle, onDelete }) {
  return (
    <div>
      <input
        type="checkbox"
        checked={todo.completed}
        onChange={() => onToggle(todo.id)}
      />
      <span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
        {todo.text}
      </span>
      <button onClick={() => onDelete(todo.id)}>刪除</button>
    </div>
  );
});

4. 性能優(yōu)化最佳實踐

4.1 合理使用依賴項

function UserProfile({ userId, onUpdate }) {
  // ? 只在 userId 或 onUpdate 變化時更新
  const handleUpdate = useCallback(() => {
    onUpdate(userId);
  }, [userId, onUpdate]);

  // ? 不必要的依賴項
  const handleClick = useCallback(() => {
    console.log('Clicked');
  }, [userId]); // userId 不需要作為依賴項
}

4.2 避免過度優(yōu)化

// ? 簡單組件不需要使用 useCallback
function SimpleButton({ onClick }) {
  return <button onClick={onClick}>Click me</button>;
}

// ? 復(fù)雜組件或頻繁重渲染的組件使用 useCallback
const ComplexComponent = React.memo(function ComplexComponent({ onAction }) {
  // 復(fù)雜的渲染邏輯
  return (
    // ...
  );
});

5. useCallback 與其他 Hooks 配合

5.1 配合 useEffect 使用

function DataFetcher({ query }) {
  const [data, setData] = useState(null);

  // 記憶獲取數(shù)據(jù)的函數(shù)
  const fetchData = useCallback(async () => {
    const response = await fetch(`/api/search?q=${query}`);
    const result = await response.json();
    setData(result);
  }, [query]);

  // 在 effect 中使用記憶的函數(shù)
  useEffect(() => {
    fetchData();
  }, [fetchData]); // fetchData 作為依賴項

  return <div>{/* 渲染數(shù)據(jù) */}</div>;
}

5.2 配合 useMemo 使用

function DataProcessor({ data, onProcess }) {
  // 記憶處理函數(shù)
  const processData = useCallback((item) => {
    // 復(fù)雜的數(shù)據(jù)處理邏輯
    return someExpensiveOperation(item);
  }, []);

  // 使用記憶的函數(shù)處理數(shù)據(jù)
  const processedData = useMemo(() => {
    return data.map(processData);
  }, [data, processData]);

  return (
    <div>
      {processedData.map(item => (
        <ProcessedItem
          key={item.id}
          item={item}
          onProcess={onProcess}
        />
      ))}
    </div>
  );
}

6. 注意事項

避免過度使用

  • 只在性能確實受影響時使用
  • 簡單組件和回調(diào)不需要使用 useCallback

正確設(shè)置依賴項

  • 包含所有回調(diào)中使用的變量
  • 避免不必要的依賴項

配合 React.memo 使用

  • 單獨使用 useCallback 可能無法帶來性能提升
  • 需要配合 React.memo 等優(yōu)化手段

考慮使用場景

  • 頻繁重渲染的組件
  • 復(fù)雜的計算或操作
  • 傳遞給多個子組件的回調(diào)

通過合理使用 useCallback 和 React.memo,我們可以有效優(yōu)化 React 應(yīng)用的性能。但要記住,過度優(yōu)化可能會適得其反,應(yīng)該在實際需要時才進(jìn)行優(yōu)化。

到此這篇關(guān)于React useCallback使用方法詳解的文章就介紹到這了,更多相關(guān)React useCallback內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解使用React進(jìn)行組件庫開發(fā)

    詳解使用React進(jìn)行組件庫開發(fā)

    本篇文章主要介紹了詳解使用React進(jìn)行組件庫開發(fā),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • react?hooks中的useState使用要點

    react?hooks中的useState使用要點

    這篇文章主要為大家介紹了react?hooks中的useState使用要點詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • React?狀態(tài)管理工具優(yōu)劣勢示例分析

    React?狀態(tài)管理工具優(yōu)劣勢示例分析

    這篇文章主要為大家介紹了React?狀態(tài)管理工具優(yōu)劣勢示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 詳解React Angular Vue三大前端技術(shù)

    詳解React Angular Vue三大前端技術(shù)

    當(dāng)前世界中,技術(shù)發(fā)展非常迅速并且變化迅速,開發(fā)者需要更多的開發(fā)工具來解決不同的問題。本文就對于當(dāng)下主流的前端開發(fā)技術(shù)React、Vue、Angular這三個框架做個相對詳盡的探究,目的是為了解開這些前端技術(shù)的面紗,看看各自的廬山真面目。
    2021-05-05
  • 詳解如何在React中監(jiān)聽鼠標(biāo)事件

    詳解如何在React中監(jiān)聽鼠標(biāo)事件

    React可以通過使用React事件系統(tǒng)來監(jiān)聽鼠標(biāo)事件,您可以在React組件中通過使用特定的事件處理函數(shù)來注冊和處理鼠標(biāo)事件,本文小編講給大家詳細(xì)介紹一下如何在React中監(jiān)聽鼠標(biāo)事件,需要的朋友可以參考下
    2023-09-09
  • react?cropper圖片裁切實例詳解

    react?cropper圖片裁切實例詳解

    這篇文章主要為大家介紹了react?cropper圖片裁切實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • react如何將字符串轉(zhuǎn)義成html語句

    react如何將字符串轉(zhuǎn)義成html語句

    這篇文章主要介紹了react如何將字符串轉(zhuǎn)義成html語句問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • react MPA 多頁配置詳解

    react MPA 多頁配置詳解

    這篇文章主要介紹了react MPA 多頁配置詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • react redux中如何獲取store數(shù)據(jù)并將數(shù)據(jù)渲染出來

    react redux中如何獲取store數(shù)據(jù)并將數(shù)據(jù)渲染出來

    這篇文章主要介紹了react redux中如何獲取store數(shù)據(jù)并將數(shù)據(jù)渲染出來,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • React動畫實現(xiàn)方案Framer Motion讓頁面自己動起來

    React動畫實現(xiàn)方案Framer Motion讓頁面自己動起來

    這篇文章主要為大家介紹了React動畫實現(xiàn)方案Framer Motion讓頁面自己動起來,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10

最新評論