<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
如果你還不熟悉勾點的概念,請務必檢視本文章,因為它對勾點的概念提供了一個非常好的、深入的概述,以及一些勾點的例子。
useCallback
勾點是用來快取一個記憶化的回撥函數,以節省任何重新計算的開銷。
這個勾點可以阻止一個元件重新渲染,除非它的道具發生了變化,這意味著我們現在可以隔離資源密集型的函數,這樣它們就不會在每個元件渲染時自動執行。
最好是展示一個有利於使用該勾點的場景,這樣我們就能更好地理解我們為達成一個問題所採取的步驟,然後再解釋使用useCallback
勾點背後的思考過程。
我們將從搭建一個全新的React專案的腳手架開始。首先,我們將建立一個新的專案目錄,之後,我們將使用終端初始化一個新專案。
在這個過程中,你可以使用npm、npx或者yarn。你要執行的命令是:
npm init react-app app-name
: npx create-react-app app-name
yarn create react-app app-name
現在我們已經設定好了一切,讓我們直接進入有趣的部分。
由於這是一個小專案,我們將把所有的程式碼放在根src
目錄下的App.js
檔案內,它看起來會是這樣的:
import { useState, memo } from "react"; import './App.css'; const Todos = ({ todos, addTodo }) => { console.log("child render"); return ( <div className="todos-container"> <h2>My Todos</h2> <div className="todos"> {todos.map((todo, index) => { return <p key={index}>{todo}</p>; })} </div> <button onClick={addTodo}>Add Todo</button> </div> ); }; const MemoizedTodos = memo(Todos); const App = () => { const [count, setCount] = useState(0); const [todos, setTodos] = useState([]); const increment = () => { setCount((c) => c + 1); }; const addTodo = () => { setTodos((t) => [...t, "New Todo"]); }; return ( <div className="App"> <MemoizedTodos todos={todos} addTodo={addTodo} /> <hr /> <div className="counter-container"> <p>Count: {count}</p> <button onClick={increment}>+</button> </div> </div> ); }; export default App;
這裡有相當多的東西需要解壓,所以讓我們看看我們有什麼。
首先,我們定義了一個Todos
元件,它的道具是一個todos列表,以及一個函數,一旦被呼叫,就會新增一個新的todo。這個元件的任務是將todos渲染到螢幕上,並在按下Add Todo
按鈕時新增一個新的todo。
然後,我們有其餘的App
元件,除了渲染和傳遞道具給MemoizedTodos
元件外,還在螢幕上顯示一個可以遞增的計數器。
而為了讓一切看起來更好一點,我們還將在我們的App.css
檔案中新增以下樣式:
.App { text-align: left; width: 80vw; margin: 5vh auto 0 auto; }
現在,你可能會問自己:"這個應用程式有什麼問題?";的確,一切似乎都在正常工作。然而,問題是,每次我們點選+
按鈕來增加計數器時,Todos
元件就會被重新渲染。
我們可以通過檢查控制檯來檢查,每次我們重新渲染Todos
元件時,都會列印到控制檯。
意外的Todos
元件的重新渲染
你看,在App
元件中,我們定義了addTodo
函數,它將在每次App
元件重新渲染時被重新建立。當App
元件的狀態發生變化時,它就會重新渲染,其中包括todos和計數器。
我們正在使用[memo](https://reactjs.org/docs/react-api.html#reactmemo)
,所以Todos
元件不應該重新渲染,因為當計數增加時,todos
的狀態和addTodo
的功能都沒有改變。
因此,基本上,問題在於addTodo
是定義在App
元件內的,並且在該元件重新生成時被重新建立。
實際上,我們有兩種方法可以解決這個問題:
App
元件之外定義addTodo
函數。addTodo
函數的記憶化雖然第一種方法似乎是明確的解決方案,但我們不能總是依靠將一個函數排除在元件的範圍之外,而使其成為一個純函數。
然後我們再來看看useCallback
勾點,它正是通過對函數進行備忘來解決我們現在面臨的這個問題,以避免其重構。
我們所要做的就是從React中匯入useCallback
勾點,並將呼叫勾點的結果與勾點的回撥返回的狀態更新分配給addTodo
函數,就這樣:
const addTodo = useCallback(() => { setTodos((t) => [...t, "New Todo"]); }, []);
而這個輕微的調整應該可以解決我們之前的問題。
現在,如果你想知道為什麼我們沒有把todos
陣列新增到勾點的依賴陣列中,那是因為React會拾取狀態,因為我們使用的是以回撥為引數的setTodos
函數,而不是一個陣列值。
如果我們要改變這一點,我們應該看到一個警告。
setState的值而不是回撥作為引數
useCallback依賴陣列的警告
我希望你喜歡讀這篇文章,並希望你對useCallback
勾點是什麼,它的作用,以及什麼時候應該使用它有了更好的理解。
以上就是React useCallback勾點的作用方法demo的詳細內容,更多關於React useCallback勾點的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45