乐趣区

关于react.js:react-hooks用起来很爽但也要注意这些

React Hooks

react hooks 的应用须要在 function component 组件中,本文讲述在应用 react hooks 中你须要留神的一些事件

状态每次扭转,整个 function 都会从新执行

可能导致:函数的每次执行,其外部定义的变量和办法都会从新创立,也就是说会从新给它们分配内存,这会导致性能受到影响

看上面这个例子:

import React, {useState, ReactElement} from 'react'
import {Button} from 'antd'

let num = 0; // 用于记录以后组件执行次数

export default (): ReactElement => {console.log('render num:', ++num) // 打印执行次数

  let [count, setCount] = useState(0)

  const handleClick = () => {setCount(++count)
  }

  return (
    <>
      <p>count: {count}</p>
      <Button type="primary" onClick={handleClick}>
        Button
      </Button>
    </>
  )
}

初始化时执行了一次:

当初我点三次按钮,让 count 状态扭转:

可见,每扭转一次 count,该组件对应的整个 function 会从新执行,其外部变量和办法会从新创立,从而影响性能。

解决办法:

  • 变量尽量放在函数内部
  • 办法应用 useCallback 包裹起来

应用办法:

const handleClick = useCallback(()=>{// 业务代码},[count])

useCallback 的作用:组件初始化时,将第一个参数函数“缓存”起来,只有在第二个参数(数组中的值)有变动时,被包裹的函数才会从新被创立,否则不会从新创立。

总结:变量尽量放在组件内部定义,函数应用 useCallback 包裹起来,防止组件 render 时反复创立。

父组件更新,子组件也跟着执行

再看个例子,咱们把下面例子作为父组件,在外面增加一个子组件.

父组件:

export default (): ReactElement => {let [count, setCount] = useState(0)

  const handleClick = useCallback(() => {setCount(++count)
  }, [count])

  return (
    <>
      <p>count: {count}</p>
      
      {/* 这里增加一个子组件 */}
      <ChildrenComponent />

      <Button type="primary" onClick={handleClick}>
        Button
      </Button>
    </>
  )
}

子组件代码:

export default (): ReactElement => {console.log('children render')

  return <div>children component</div>
}

当初我再点三次按钮,让父组件 render 三次:

大爷的,子组件打印三次,示意执行了三次。

这必定不是我想要的,我想要的是子组件须要被渲染的时候再去执行,那么如何解决?

答:应用 React.memo

React.memo 相似 class 组件里的 PureComponent , 能帮忙咱们管制适合从新渲染组件。

留神:说它相似,但不齐全一样,它更像是 PureComponent + shouldComponentUpdate 的联合。
PureComponent 通过 props 和 state 的浅比拟来判断要不要从新渲染组件。

那么在 react hooks 里如何去写呢

咱们把子组件加上 React.memo :

export default React.memo((): ReactElement => {console.log('children render')

    return <div>children component</div>
  },
)

当初再点三次按钮:

可见,子组件不再打印,也就是不再执行了。

React.memo 也提供了 shouldComponentUpdate 性能,用于自定义比拟来决定是否渲染:


React.memo(MyComponent, (prevProps, nextProps)=>{
 // 如果传递 nextProps 渲染会返回与传递 prevProps 渲染雷同的后果,则返回 true,否则返回 false.
 
 // return true: 不渲染  return false: 渲染
})

总结

  • 应用 useCallback 缓存定义的函数
  • 应用 React.memo 防止不必要的 render

如果有更好的倡议,请留言,多谢

退出移动版