成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

React 新特性 Hooks 講解及實例(三)

_Dreams / 2785人閱讀

摘要:來個使用類形式的例子以上就不說解釋了,第一篇已經(jīng)講過了,接著將改成用的形式接著使用形式接收一個對象的返回值并返回該的當前值。如果的返回值是函數(shù)的話,那么就可以簡寫成的方式,只是簡寫而已,實際并沒有區(qū)別。

本文是 React 系列的第三篇

React 新特性講解及實例(一)

React 新特性 Hooks 講解及實例(二)

想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!

使用 Context Hooks

使用 Context ,首先頂層先聲明 Provier 組件,并聲明 value 屬性,接著在后代組件中聲明 Consumer 組件,這個 Consumer 子組件,只能是唯一的一個函數(shù),函數(shù)參數(shù)即是 Context 的負載。如果有多個 Context ,ProviderConsumer 任意的順序嵌套即可。

此外我們還可以針對任意一個 Context 使用 contextType 來簡化對這個 Context 負載的獲取。但在一個組件中,即使消費多個 Context,contextType 也只能指向其中一個

在 Hooks 環(huán)境中,依舊可以使用 Consumer,但是 ContextType 作為類靜態(tài)成員肯定是用不了。Hooks 提供了 useContext,不但解決了 Consumer 難用的問題同時也解決了 contextType 只能使用一個 context 的問題。

來個使用類形式的例子:

class Foo extends Component {
  render() {
    return (
      
        {
          count => 

{count}

}
) } } function App (props) { const [count, setCount] = useState(0); return (
) }

以上就不說解釋了,第一篇已經(jīng)講過了,接著將 Foo 改成用 contextType 的形式:

class Foo extends Component {
  static contextType = CountContext;
  render() {
    const count = this.context
    return (
      

{count}

) } }

接著使用 useContext 形式:

function Foo () {
  const count = useContext(CountContext)
  return (
    

{count}

) }

useContext 接收一個 context 對象(React.createContext 的返回值)并返回該 context 的當前值。當前的 context 值由上層組件中距離當前組件最近的 的 value prop 決定。

當組件上層最近的 更新時,該 Hook 會觸發(fā)重渲染,并使用最新傳遞給 CountContext provider 的 context value 值。

別忘記 useContext 的參數(shù)必須是 context 對象本身:

正確: useContext(MyContext)

錯誤: useContext(MyContext.Consumer)

錯誤: useContext(MyContext.Provider)

調(diào)用了 useContext 的組件總會在 context 值變化時重新渲染。如果重渲染組件的開銷較大,你可以 通過使用 memoization 來優(yōu)化。

使用 Memo Hooks

meno 用來優(yōu)化函數(shù)組件重渲染的行為,當傳入屬性值都不變的情況下,就不會觸發(fā)組件的重渲染,否則就會觸發(fā)組件重渲染。

useMemo 與 memo

meno針對的是一個組件的渲染是否重復(fù)執(zhí)行,而 useMemo 定義的是一個函數(shù)邏輯是否重復(fù)執(zhí)行。

來個粟子:

function Foo (props) {
  return (
    

{props.count}

) } function App (props) { const [count, setCount] = useState(0); const double = useMemo(() => { return count * 2 }, [count]) return (
) }

運行結(jié)果:

如上所示,useMemo 語法與 useEffect 是一致的。第一個參數(shù)是需要執(zhí)行的邏輯函數(shù),第二個參數(shù)是這個邏輯依賴輸入變量組成的數(shù)組,如果不傳第二個參數(shù),這 useMemo 的邏輯每次就會運行,useMemo 本身的意義就不存在了,所以需要傳入?yún)?shù)。所以傳入空數(shù)組就只會運行一次,策略與 useEffect 是一樣的,但有一點比較大的差異就是調(diào)用時機,useEffect 執(zhí)行的是副作用,所以一定是渲染之后才執(zhí)行,但 useMemo 是需要返回值的,而返回值可以直接參與渲染,因此 useMemo 是在渲染期間完成的。

接下來改造一下 useMemo,讓它依賴 count 如下:

const double = useMemo(() => {
  return count * 2
}, [count])

接著只有當 count 變化時,useMemo 才會執(zhí)行。

再次修改 useMemo, 如下:

const double = useMemo(() => {
  return count * 2
}, [count === 3])

現(xiàn)在能斷定,count 在等于 3 之前,由于這個條件一直保存 false 不變,double 不會重新計算,所以一直是 0,當 count 等于 3,double 重新計算為 6,當 count 大于 3,double 在重新計算,變成 8,然后就一直保存 8 不變。

記住,傳入的 useMemo 的函數(shù)會在渲染期間執(zhí)行,請不要在這個函數(shù)內(nèi)部執(zhí)行與渲染無關(guān)的聽任,諸如副作用這類操作屬于 useEffect 的適用范疇,而不是 useMemo。

你可以把 useMemo 作為性能優(yōu)化的手段,但不要把它當成語義上的保證。

使用 useCallback Hooks

接下先看一下使用 memo 優(yōu)化子組件的例子。

const Foo = memo (function Foo (props) {
  console.log("Counter render")
  return (
    

{props.count}

) }) function App (props) { const [count, setCount] = useState(0); const double = useMemo(() => { return count * 2 }, [count === 3]) return (
) }

使用 memo 包裹 Foo 組件,這樣只有當 double 變化時,Foo 組件才會重新渲染,執(zhí)行里面的 log,運行結(jié)果如下:

現(xiàn)在在給 Foo 中的 h1 添加一個 click 事件:

const Foo = memo (function Foo (props) {
  console.log("Counter render")
  return (
    

{props.count}

) })

然后在 App 組件中聲明 onClick 并傳給 Foo 組件:

function App (props) {
  ...
  const onClick = () => {
    console.log("Click")
  }

  return (
    
...
) }

看下運行效果:

可以看出,每次點擊,不管 double 是否有變化, Foo 組件都會被渲染。那就說明每次 App 重新渲染之后, onClick 句柄的變化,導(dǎo)致 Foo 也被連帶重新渲染了。count 經(jīng)常變化可以理解,但是 onClick 就不應(yīng)該經(jīng)常變化了,畢竟只是一個函數(shù)而已,所以我們要想辦法讓 onClick 句柄不變化。

想想我們上面講的 useMemo,可以這樣來優(yōu)化 onClick:

const onClick = useMemo(() => {
  return () => {
    console.log("Click")
  }
}, [])

由于我們傳給 useMemo 的第二個參數(shù)是一個空數(shù)組,那么整個邏輯就只會運行一次,理論上我們返回的 onClick 就只有一個句柄。

運行效果:

現(xiàn)在我們把 useCallback 來實現(xiàn)上頁 useMemo 的邏輯。

const onClick = useCallback(() => {
  console.log("Click")
},[])

如果 useMemo 返回的是一個函數(shù),那么可以直接使用 useCallback 來省略頂層的函數(shù)。

useCallback(fn, deps) 相當于 useMemo(() => fn, deps)

大家可能有一個疑問,useCallback 這幾行代碼明明每次組件渲染都會創(chuàng)建新的函數(shù),它怎么就優(yōu)化性能了呢。

注意,大家不要誤會,使用 useCallback 確實不能阻止創(chuàng)建新的函數(shù),但這個函數(shù)不一定會被返回,也就是說這個新創(chuàng)建的函數(shù)可能會被拋棄。useCallback解決的是解決的傳入子組件的函數(shù)參數(shù)過多變化,導(dǎo)致子組件過多渲染的問題,這里需要理解好。

上述我們第二個參數(shù)傳入的空數(shù)組,在實際業(yè)務(wù)并沒有這么簡單,至少也要更新一下狀態(tài)。舉個粟子:

function App (props) {
  ... 
  const [clickCount, setClickCount] = useState(0);
  const onClick = useCallback(() => {
    console.log("Click")
    setClickCount(clickCount + 1)
  },[clickCount, setClickCount])
  ...
}

在 APP 組件中在聲明一個 useState,然后在 onClick 中調(diào)用 setClickCount,此時 onClick 依賴 clickCount,setClickCount。

其實這里的 setClickCount 是不需要寫的,因為 React 能保證 setState 每次返回的都是同個句柄。不信,可以看下官方文檔 :

這里的場景,除了直接使用 setClickCount + 1 賦值以外, 還有一種方式甚至連 clickCount都不用依賴。setState 除了傳入對應(yīng)的 state 最新值以外,還可以傳入一個函數(shù),函數(shù)的參數(shù)即這個 state 的當前值,返回就是要更新的值:

const onClick = useCallback(() => {
  console.log("Click")
  setClickCount((clickCount) => clickCount + 1)
},[])

小結(jié)

memo 根據(jù)屬性來決定是否重新渲染組件一樣,useMemo 可以根據(jù)指定的依賴不決定一段函數(shù)邏輯是否重新執(zhí)行,從而優(yōu)化性能。

如果 useMemo 的返回值是函數(shù)的話,那么就可以簡寫成 useCallback 的方式,只是簡寫而已,實際并沒有區(qū)別。

需要特別注意的是,當依賴變化時,我們能斷定 useMemo 一定重新執(zhí)行。但是,即使依賴不變化我們不能假定它就一定不會重新執(zhí)行,也就是說,它可以會執(zhí)行,就是考慮內(nèi)在優(yōu)化結(jié)果。

我們可以把 useMemo, useCallback 當做一個錦上添花優(yōu)化手段,不可以過度依賴它是否重新渲染,因為 React 目前沒有打包票說一定執(zhí)行或者一定不執(zhí)行。

交流

干貨系列文章匯總?cè)缦?,覺得不錯點個Star,歡迎 加群 互相學(xué)習。

https://github.com/qq44924588...

我是小智,公眾號「大遷世界」作者,對前端技術(shù)保持學(xué)習愛好者。我會經(jīng)常分享自己所學(xué)所看的干貨,在進階的路上,共勉!

關(guān)注公眾號,后臺回復(fù)福利,即可看到福利,你懂的。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105030.html

相關(guān)文章

  • React 特性 Hooks 講解實例(四)

    摘要:粟例說明一下獲取子組件或者節(jié)點的句柄指向已掛載到上的文本輸入元素本質(zhì)上,就像是可以在其屬性中保存一個可變值的盒子。粟例說明一下渲染周期之間的共享數(shù)據(jù)的存儲上述使用聲明兩個副作用,第一個每隔一秒對加,因為只需執(zhí)行一次,所以每二個參為空數(shù)組。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! React 新特性講解及實例(一) React 新特性 Hooks 講解及實...

    aboutU 評論0 收藏0
  • React 特性 Hooks 講解實例(二)

    摘要:還可以返回另一個回調(diào)函數(shù),這個函數(shù)的執(zhí)行時機很重要。對于第二個我們可以通過返回一個回調(diào)函數(shù)來注銷事件的注冊?;卣{(diào)函數(shù)在視圖被銷毀之前觸發(fā),銷毀的原因有兩種重新渲染和組件卸載。 本文是 React 系列的第二篇 React 新特性講解及實例(一) 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 什么是 Hooks Hook 是 React 16.8 的新增特性。它可...

    zero 評論0 收藏0
  • React 特性講解實例(一)

    摘要:接收一個屬性,這個組件會讓后代組件統(tǒng)一提供這個變量值。因此對于同一個對象而言,一定是后代元素。解決方法就是把內(nèi)聯(lián)函數(shù)提取出來,如下講了這么多,我們還沒有講到其實我們已經(jīng)講完了的工作原理了。 本節(jié)主要講解以下幾個新的特性: Context ContextType lazy Suspense 錯誤邊界(Error boundaries) memo 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博...

    Betta 評論0 收藏0
  • React Hooks 解析(下):進階

    摘要:第一次了解這項特性的時候,真的有一種豁然開朗,發(fā)現(xiàn)新大陸的感覺。在絕大多數(shù)情況下,是更好的選擇。唯一例外的就是需要根據(jù)新的來進行操作的場景。會保證在頁面渲染前執(zhí)行,也就是說頁面渲染出來的是最終的效果。上面條規(guī)則都是為了保證調(diào)用順序的穩(wěn)定性。 歡迎關(guān)注我的公眾號睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、...

    APICloud 評論0 收藏0
  • 上課程推薦:《React Hooks 案例詳解(React 進階必備)》

    摘要:課程制作和案例制作都經(jīng)過精心編排。對于開發(fā)者意義重大,希望對有需要的開發(fā)者有所幫助。是從提案轉(zhuǎn)為正式加入的新特性。并不需要用繼承,而是推薦用嵌套。大型項目中模塊化與功能解耦困難。從而更加易于復(fù)用和獨立測試。但使用會減少這種幾率。 showImg(https://segmentfault.com/img/bVbpNRZ?w=1920&h=1080); 講師簡介 曾任職中軟軍隊事業(yè)部,參與...

    Lin_YT 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<