摘要:粟例說(shuō)明一下獲取子組件或者節(jié)點(diǎn)的句柄指向已掛載到上的文本輸入元素本質(zhì)上,就像是可以在其屬性中保存一個(gè)可變值的盒子。粟例說(shuō)明一下渲染周期之間的共享數(shù)據(jù)的存儲(chǔ)上述使用聲明兩個(gè)副作用,第一個(gè)每隔一秒對(duì)加,因?yàn)橹恍鑸?zhí)行一次,所以每二個(gè)參為空數(shù)組。
想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你!
React 新特性講解及實(shí)例(一)
React 新特性 Hooks 講解及實(shí)例(二)
React 新特性 Hooks 講解及實(shí)例(三)
使用 Ref Hooks類組件中使用 Ref 一般有:
String Ref
Callback Ref
CreateRef
上述在函數(shù)組件中沒有辦法使用它們,取而代之的是 useRef Hooks。
useRef 主要有兩個(gè)使用場(chǎng)景:
獲取子組件或者 DOM 節(jié)點(diǎn)的句柄
渲染周期之間的共享數(shù)據(jù)的存儲(chǔ)
大家可能會(huì)想到 state 也可跨越渲染周期保存,但是 state 的賦值會(huì)觸發(fā)重渲染,但是 ref 不會(huì),從這點(diǎn)看 ref 更像是類屬性中的普通成員。
粟例說(shuō)明一下:獲取子組件或者 DOM 節(jié)點(diǎn)的句柄
function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { // `current` 指向已掛載到 DOM 上的文本輸入元素 inputEl.current.focus(); }; return ( <> > ); }
本質(zhì)上,useRef 就像是可以在其 .current 屬性中保存一個(gè)可變值的“盒子”。
粟例說(shuō)明一下:渲染周期之間的共享數(shù)據(jù)的存儲(chǔ)
function App (props) { const [count, setCount] = useState(0); let it useEffect(() => { it = setInterval(() => { setCount(count => count + 1) }, 1000) } , []) useEffect(() => { if (count >= 5) { clearInterval(it) } }) return () }{count}
上述使用 useEffect 聲明兩個(gè)副作用,第一個(gè)每隔一秒對(duì) count 加 1,因?yàn)橹恍鑸?zhí)行一次,所以每二個(gè)參為空數(shù)組。第二個(gè) useEffect 判斷 count 大于等于時(shí),停止對(duì) count 的操作。
運(yùn)行結(jié)果:
顯示當(dāng) count 為 5 的時(shí)候并沒有停止,這是為什么呢?
因?yàn)樵?clearInterval, it 這個(gè)變量已經(jīng)不是 setInterval 賦值時(shí)的那個(gè)了,每次 App 重渲染都會(huì)重置它。這時(shí)候就可以使用 useRef 來(lái)解決這個(gè)問題。
function App (props) { const [count, setCount] = useState(0); const it = useRef(null) useEffect(() => { it.current = setInterval(() => { setCount(count => count + 1) }, 1000) } , []) useEffect(() => { if (count >= 5) { clearInterval(it.current) } }) return ( ... ) }
使用 useRef 來(lái)創(chuàng)建一個(gè) it, 當(dāng) setInterval 返回的結(jié)果賦值給 it 的 current 屬性。
運(yùn)行結(jié)果:
你應(yīng)該熟悉 ref 這一種訪問 DOM 的主要方式。如果你將 ref 對(duì)象以 形式傳入組件,則無(wú)論該節(jié)點(diǎn)如何改變,React 都會(huì)將 ref 對(duì)象的 .current 屬性設(shè)置為相應(yīng)的 DOM 節(jié)點(diǎn)。
然而,useRef() 比 ref 屬性更有用。它可以很方便地保存任何可變值,其類似于在 class 中使用實(shí)例字段的方式。
這是因?yàn)樗鼊?chuàng)建的是一個(gè)普通 Javascript 對(duì)象。而 useRef() 和自建一個(gè) {current: ...} 對(duì)象的唯一區(qū)別是,useRef 會(huì)在每次渲染時(shí)返回同一個(gè) ref 對(duì)象。
請(qǐng)記住,當(dāng) ref 對(duì)象內(nèi)容發(fā)生變化時(shí),useRef 并不會(huì)通知你。變更 .current 屬性不會(huì)引發(fā)組件重新渲染。如果想要在 React 綁定或解綁 DOM 節(jié)點(diǎn)的 ref 時(shí)運(yùn)行某些代碼,則需要使用回調(diào) ref 來(lái)實(shí)現(xiàn)。自定義 Hook
前面三篇,我們講到優(yōu)化類組件的三大問題:
方便復(fù)用狀態(tài)邏輯
副作用的關(guān)注點(diǎn)分離
函數(shù)組件無(wú) this 問題
對(duì)于組件的復(fù)用狀態(tài)沒怎么說(shuō)明,現(xiàn)在使用自定義 Hook 來(lái)說(shuō)明一下。
首先我們把上面的例子用到 count 的邏輯的用自定義 Hook 封裝起來(lái):
function useCount(defaultCount) { const [count, setCount] = useState(defaultCount); const it = useRef() useEffect(() => { it.current = setInterval(() => { setCount(count => count + 1) }, 1000) } , []) useEffect(() => { if (count >= 5) { clearInterval(it.current) } }) return [count, setCount] } function App (props) { const [count, setCount] = useCount(0); return () }{count}
運(yùn)行效果:
可以看出運(yùn)行效果跟上面是一樣的。
定義 Hook 是一個(gè)函數(shù),其名稱以 “use” 開頭,函數(shù)內(nèi)部可以調(diào)用其他的 Hook。我們?cè)诤瘮?shù)自定義寫法上似乎和編寫函數(shù)組件沒有區(qū)別,確實(shí)自定義組件與函數(shù)組件的最大區(qū)別就是輸入與輸出的區(qū)別。
再來(lái)一個(gè)特別的 Hook 加深一下映像。在上述代碼不變的條件下,我們?cè)诩右粋€(gè)自定義 Hook 內(nèi)容如下:
function useCounter(count) { return ({count}
) }
在 App 組件調(diào)用:
function App (props) { const [count, setCount] = useCount(0); const Counter = useCounter(count) return ({Counter}) }
運(yùn)行效果:
我們自定義 useCounter Hook返回的是一個(gè) JSX,運(yùn)行效果是一樣的,所以 Hook 是可以返回 JSX 來(lái)參與渲染的,更說(shuō)明 Hook 與函數(shù)組件的相似性。
使用 Hook 的法則 只在最頂層使用 Hook不要在循環(huán),條件或嵌套中調(diào)用 Hook,確保總是在你的 React 函數(shù)的最頂層調(diào)用他們。遵守這條規(guī)則,你就能確保 Hook 在每一次渲染中都按照同樣的順序被調(diào)用。這上 React 能夠在多次的 useState 和 useEffect 調(diào)用之間保持 hook 狀態(tài)的正確。
只在 React 函數(shù)中調(diào)用 Hook不要在普通的 JavaScript 函數(shù)中調(diào)用 Hook, 你可以:
在 React 的函數(shù)組件中調(diào)用 Hook
在自定義 Hook 中調(diào)用其它 Hook
Hooks 常見問題以下主要說(shuō)明幾個(gè)典型的問題,當(dāng)然這在官網(wǎng)上都有說(shuō)明。
生命周期方法要如何對(duì)應(yīng)到 Hook?constructor:函數(shù)組件不需要構(gòu)造函數(shù)。你可以通過(guò)調(diào)用 useState 來(lái)初始化 state。如果計(jì)算的代價(jià)比較昂貴,你可以傳一個(gè)函數(shù)給 useState。
getDerivedStateFromProps:改為 在渲染時(shí) 安排一次更新
shouldComponentUpdate:詳見官網(wǎng).
render:這是函數(shù)組件體本身。
componentDidMount, componentDidUpdate, componentWillUnmount:useEffect Hook 可以表達(dá)所有這些(包括 不那么 常見 的場(chǎng)景)的組合。
componentDidCatch and getDerivedStateFromError:目前還沒有這些方法的 Hook 等價(jià)寫法,但很快會(huì)加上。
如何強(qiáng)制更新一個(gè) Hooks 組件如果前后兩次的值相同,useState 和 useReducer Hook 都會(huì)放棄更新。原地修改 state 并調(diào)用 setState 不會(huì)引起重新渲染。
通常,你不應(yīng)該在 React 中修改本地 state。然而,作為一條出路,你可以用一個(gè)增長(zhǎng)的計(jì)數(shù)器來(lái)在 state 沒變的時(shí)候依然強(qiáng)制一次重新渲染:
const [ignored, forceUpdate] = useReducer(x => x + 1, 0); function handleClick() { forceUpdate(); }
可能的話盡量避免這種模式。
交流干貨系列文章匯總?cè)缦?,覺得不錯(cuò)點(diǎn)個(gè)Star,歡迎 加群 互相學(xué)習(xí)。
https://github.com/qq44924588...
我是小智,公眾號(hào)「大遷世界」作者,對(duì)前端技術(shù)保持學(xué)習(xí)愛好者。我會(huì)經(jīng)常分享自己所學(xué)所看的干貨,在進(jìn)階的路上,共勉!
關(guān)注公眾號(hào),后臺(tái)回復(fù)福利,即可看到福利,你懂的。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/105587.html
摘要:來(lái)個(gè)使用類形式的例子以上就不說(shuō)解釋了,第一篇已經(jīng)講過(guò)了,接著將改成用的形式接著使用形式接收一個(gè)對(duì)象的返回值并返回該的當(dāng)前值。如果的返回值是函數(shù)的話,那么就可以簡(jiǎn)寫成的方式,只是簡(jiǎn)寫而已,實(shí)際并沒有區(qū)別。 本文是 React 系列的第三篇 React 新特性講解及實(shí)例(一) React 新特性 Hooks 講解及實(shí)例(二) 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著...
摘要:還可以返回另一個(gè)回調(diào)函數(shù),這個(gè)函數(shù)的執(zhí)行時(shí)機(jī)很重要。對(duì)于第二個(gè)我們可以通過(guò)返回一個(gè)回調(diào)函數(shù)來(lái)注銷事件的注冊(cè)。回調(diào)函數(shù)在視圖被銷毀之前觸發(fā),銷毀的原因有兩種重新渲染和組件卸載。 本文是 React 系列的第二篇 React 新特性講解及實(shí)例(一) 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 什么是 Hooks Hook 是 React 16.8 的新增特性。它可...
摘要:返回元素的是將新的與原始元素的淺層合并后的結(jié)果。生命周期方法要如何對(duì)應(yīng)到函數(shù)組件不需要構(gòu)造函數(shù)。除此之外,可以認(rèn)為的設(shè)計(jì)在某些方面更加高效避免了需要的額外開支,像是創(chuàng)建類實(shí)例和在構(gòu)造函數(shù)中綁定事件處理器的成本。 React系列 React系列 --- 簡(jiǎn)單模擬語(yǔ)法(一)React系列 --- Jsx, 合成事件與Refs(二)React系列 --- virtualdom diff算法實(shí)...
摘要:第一次了解這項(xiàng)特性的時(shí)候,真的有一種豁然開朗,發(fā)現(xiàn)新大陸的感覺。在絕大多數(shù)情況下,是更好的選擇。唯一例外的就是需要根據(jù)新的來(lái)進(jìn)行操作的場(chǎng)景。會(huì)保證在頁(yè)面渲染前執(zhí)行,也就是說(shuō)頁(yè)面渲染出來(lái)的是最終的效果。上面條規(guī)則都是為了保證調(diào)用順序的穩(wěn)定性。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、...
摘要:接收一個(gè)屬性,這個(gè)組件會(huì)讓后代組件統(tǒng)一提供這個(gè)變量值。因此對(duì)于同一個(gè)對(duì)象而言,一定是后代元素。解決方法就是把內(nèi)聯(lián)函數(shù)提取出來(lái),如下講了這么多,我們還沒有講到其實(shí)我們已經(jīng)講完了的工作原理了。 本節(jié)主要講解以下幾個(gè)新的特性: Context ContextType lazy Suspense 錯(cuò)誤邊界(Error boundaries) memo 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博...
閱讀 2642·2021-09-02 15:40
閱讀 1622·2019-08-30 15:54
閱讀 1135·2019-08-30 12:48
閱讀 3464·2019-08-29 17:23
閱讀 1099·2019-08-28 18:04
閱讀 3714·2019-08-26 13:54
閱讀 656·2019-08-26 11:40
閱讀 2468·2019-08-26 10:15