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 (
    <>
      

count: {count}

) }

初始化时执行了一次:

react hooks用起来很爽,但也要注意这些_第1张图片

现在我点三次按钮,让 count 状态改变:

react hooks用起来很爽,但也要注意这些_第2张图片

可见,每改变一次 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 (
    <>
      

count: {count}

{/* 这里添加一个子组件 */} ) }

子组件代码:

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

  return 
children component
}

现在我再点三次按钮,让父组件 render 三次:
react hooks用起来很爽,但也要注意这些_第3张图片

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

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

答:使用 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 
children component
}, )

现在再点三次按钮:

react hooks用起来很爽,但也要注意这些_第4张图片

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

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


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

总结

  • 使用 useCallback 缓存定义的函数
  • 使用 React.memo 避免不必要的 render

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

你可能感兴趣的:(react.js,前端,es6,javascript)