hooks 系列五:useCallback

快來加入咱們吧!

"小和山的菜鳥們",爲前端開發者提供技術相關資訊以及系列基礎文章。爲更好的用戶體驗,請您移至咱們官網小和山的菜鳥們 ( xhs-rookies.com/ ) 進行學習,及時獲取最新文章。html

"Code tailor" ,若是您對咱們文章感興趣、或是想提一些建議,微信關注 「小和山的菜鳥們」 公衆號,與咱們取的聯繫,您也能夠在微信上觀看咱們的文章。每個建議或是贊同都是對咱們極大的鼓勵!前端

前言

這篇文章,咱們主要目的是瞭解一下 (useCallback) 的使用.react

useCallback

定義

useCallback 返回一個 memoized 回調函數。git

const memoizedCallback = useCallback(fn, deps)
複製代碼

useCallback 所需參數github

  • fn :一個函數最終會返回該回調函數,該回調函數僅僅只在 deps 參數發生改變時纔會更新。
  • deps : 用於觸發 fn 回調函數改變的參數列表。

注意: deps 是一個數組,也就是說改變 fn 的參數能夠有不少。web

把內聯回調函數及依賴項數組做爲參數傳入 useCallback,它將返回該回調函數的 memoized 版本,該回調函數僅在某個依賴項改變時纔會更新。當你把回調函數傳遞給通過優化的並使用引用相等性去避免非必要渲染(例如 shouldComponentUpdate)的子組件時,它將很是有用。npm

如何使用

咱們先來看一個簡單的例子。數組

這個是一個子組件,接受父類的一個 fn 方法並展現其按鈕。瀏覽器

const ChildComponent = memo(function (props) {
  console.log('child render!')
  return <Button onClick={props.fn}> showTime</Button>
})
複製代碼

注意: 這裏的 memo 也是一個 Hooks , 詳情請見Hook API 索引 – React (reactjs.org)微信

這是一個父組件,裏面有一個計數器,一個數字增長按鈕,和這個子組件。

function Main() {
  const [count, setcount] = useState(0)

  const ShowTime = () => {
    console.log('now time :' + new Date())
  }

  return (
    <Row style={{ 'flex-direction': 'column', }} > <Col> <Title>index:{count}</Title> </Col> <Col> <Button onClick={() => setcount(count + 1)}>increase</Button> </Col> <Col> <ChildComponent fn={ShowTime} /> </Col> </Row>
  )
}
複製代碼

咱們能夠看到,在咱們點擊 increase 按鈕的時候,count 發生了增長,這是正常且合理的。

60cv4-43wz0.gif

可是這個時候咱們打開咱們的瀏覽器控制檯,就會發現子組件 ChildComponent 在不停的 render

這是不合理的,對於咱們來講,子組件應該只受 childname 該參數的影響,若是該參數函數 fn 沒發生改變,咱們就不該該去 render

注意: 這個地方子組件不停 render 的緣由在於,這個 ShowTime 方法在不停的從新建立,而後致使傳給子組件的 props 實際上是不同的,所以致使不停 render

這個時候咱們就用到了 useCallback

function Main() {
  const [count, setcount] = useState(0)

  const useMemoryCallback = useCallback(() => {
    console.log('now time :' + new Date())
  }, [])

  return (
    <Row style={{ 'flex-direction': 'column', marginLeft: '10px', }} > <Col> <Title>index:{count}</Title> </Col> <Col> <Button onClick={() => setcount(count + 1)}>increase</Button> </Col> <Col> <ChildComponent fn={useMemoryCallback} /> </Col> </Row>
  )
}
複製代碼

這個時候,咱們將這個函數放在 useCallback 中返回,由於 deps 參數爲空,因此並無須要改變的,這樣子咱們在點擊 increase 按鈕的時候就不會觸發子組件的 render 了。

如何檢查

依賴項數組(deps)不會做爲參數傳給回調函數。雖然從概念上來講它表現爲:全部回調函數中引用的值都應該出如今依賴項數組中。將來編譯器會更加智能,屆時自動建立數組將成爲可能。

咱們推薦啓用 eslint-plugin-react-hooks 中的 exhaustive-deps 規則。此規則會在添加錯誤依賴時發出警告並給出修復建議。

小結

  • useCallback 給咱們帶來了記憶函數,結合子組件和 useMemo 能夠達到優化組件加載的效果。
  • 若是子組件接受了一個方法做爲屬性,咱們在使用 React.memo 這種避免子組件作不必的渲染時候,就須要用 useCallback 進行配合,不然 React.memo 將無心義。

下節預告

在下節中,咱們將爲你們介紹 hook 規則 ,敬請期待!

相關文章
相關標籤/搜索