useCallback memo useMemo useEffect 用法详解

背景:

今天花时间把前端的代码整理了一下,有很多地方值得记录以加深学习印象,最主要的还是react的新特性,项目中大量用到了useCallback,memo,useMemo,useEffect,下面就这些特性来说明,用自己的语言组织来说了.

useEffect

effect即副作用,即别的数据的变化会重新调用此副作用里的函数.

useEffect(()=>{
   console.log('mount');
   return ()=>{
      console.log('did update done')
  }
},[name])

当name的值改变的时候,会重新mount,这个方法在项目中有很多处的应用,比如搜索表格数据,name即搜索条件,当name重新被赋值的时候即重新拉取表格数据,如果有多个搜索条件的时候也可以加到依赖中.

副作用函数里的return则是在页面被卸载时调用.

useEffect相当于老版本class里的componentDidMount,componentDidUpdate,componentWillUnmount等生命周期的集合,这个hooks在项目中属于基本的应用,也是必须掌握的.

 

memo

这个hook是针对组件的,减少组件的不必要更新.

子组件

const TextCell = memo(function(props:any) {
  console.log('我重新渲染了')
  return (
    <p onClick={props.click}>ffff</p>
  )
})

父组件
const fatherComponent = () => {
const [number,setNumber] = useState(0);
 return(
    <div>
      模块{number}
      <TextCell/>

      <Button onClick={()=>setNumber(number => number + 1)}>加加加</Button>
    </div>
  )
}

在这里如果没有用到memo 每次父组件重新setNumber,子组件都会重新渲染一次,加上了后只会在初始化的时候渲染,减少了子组件渲染的次数,这个在之前老的class方法,要减少子组件的渲染,可以使用pureComponent,或者在生命周期 componentWillReciveProps方法里返回false即可.

 

useCallback

这个hook主要是针对函数的,为什么会有这个hook呢?

比如:

子组件

const TextCell = memo(function(props:any) {
  console.log('我重新渲染了')
  return (
    <p onClick={props.click}>ffff</p>
  )
})

父组件
const fatherComponent = () => {
const [number,setNumber] = useState(0);

const handleClick = useCallback(()=>{
   console.log(33)
},[])
 return(
    <div>
      模块{number}
      <TextCell click={handleClick}/>

      <Button onClick={()=>setNumber(number => number + 1)}>加加加</Button>
    </div>
  )
}

这里如果不使用useCallback,哪怕子组件用memo包裹了 也还是会更新子组件,因为子组件的绑定的函数click在父组件更新的时候也会更新引用地址,导致子组件的更新,但是这个其实是没必要的更新,绑定的函数并不需要子组件更新,useCallback就是阻止这类没必要的更新而存在的. 如果是用class的方法的话,需要在constructor里绑定函数,会比较麻烦,不易阅读.

这里需要注意的是 如果是有参数需要传递,则需要这样写

<TextCell click={useCallback(()=>handleClick(‘传递的参数’),[])}/>

 

useMemo

useMemo会在页面初始化的时候执行一次,并把执行的结果缓存一份

const fatherComponent = () => {
function expensiveFn() {
  let result = 0;
  for (let i = 0; i < 10000; i++) {
    result += i;
  }
  console.log(result)
  return result;
}

const base = useMemo(expensiveFn, [number]);
return (
   <div>{base}</div> 
)
}

在这个地方如果没有使用useMemo而是 直接用 const base = expensiveFn(),则在页面每次刷新的时候都会重新调用这个方法,影响页面的性能,而如果使用上了useMemo,react会把expensiveFn的执行结果缓存一份,即使页面刷新了,也不会再执行expensiveFn函数.useCallback和useMemo的区别其实就是前者是缓存过程,而后者是缓存结果.这个在页面上有时候会应用到select里的选项数据源的上下级联动.这里的数据源一般不会改变.

最后总结:

这里就说这么多了,16版本的react在很多写法真的做了很多升级,不适应也是很正常的,老的方式在性能上其实也不会很差,如果追求性能极限以上的内容都是可以参考的,掌握以上的内容react新版本的功能便可以掌握70%了,剩余的一些用法其实并不常用,像自定义hook,useContext,useRecduer

Author: kaykie

发表评论

邮箱地址不会被公开。