why React 函数式组件

最近工作一直用的class组件,很久没碰函数式组件了,现在做个总结,也算是温习了。打算这波回顾之后就用函数式组件。

先说why not class

class组件有他的优势,比如模板傻瓜式,很容易上手,生命周期也帮我们提前内置了,很省心。但其实还存在很多不足

  • 状态逻辑难复用: 在组件之间复用状态逻辑很难,可能要用到 render props (渲染属性)或者 HOC(高阶组件),但无论是渲染属性,还是高阶组件,都会在原先的组件外包裹一层父容器(一般都是 div 元素),导致层级冗余

  • 趋向复杂难以维护:

在生命周期函数中混杂不相干的逻辑(如:在 componentDidMount 中注册事件以及其他的逻辑,在 componentWillUnmount 中卸载事件,这样分散不集中的写法,很容易写出 bug )

类组件中到处都是对状态的访问和处理,导致组件难以拆分成更小的组件

  • this 指向问题:父组件给子组件传递函数时,必须绑定 this

那么这些不足可以解决吗?可以,用函数式组件

const Hello = (props) => {
return <div>{props.message}</div>
}
复制代码

但是呢,函数式组件相比class组件缺了state和生命周期。

神说要有光,这世间便有了光

react 16.8.0 推出了 hooks api ,其中 useState 解决了没有 state 的问题

const App = props => {
  const [n,setN] = useState(0) //n是读,setN是写,0 是 n 的初始值
  const onClick = () => {
    setN(n + 1)
    }
  return (
    <div>
      {n}
      <button onClick = {onClick} >+1</button>
    </div>
  )
}
复制代码

hooks api 中的 useEffect 解决了没有生命周期的问题

  • 函数组件执行的时候就相当于 constructor
  • 模拟 componentDidMount
useEffect(()=>{ console.log('第一次渲染') },[])
复制代码
  • 模拟 componentDidUpdate
useEffect(()=>{ console.log('任意属性变更')})
useEffect(()=>{ console.log('n 变了')}, [n])
复制代码
  • 模拟 componentWillUnmount
useEffect(()=>{
console.log('第一次渲染')
return ()=>{
console.log('组件要挂了')
}
})
复制代码
  • 模拟 shouldComponentUpdate

React.memo 和 useMemo 解决

  • 模拟 render

函数组件的返回值就是 render 的返回值

所以函数式组件不仅可以避免 class 组件的很多不足,还更加灵活自由,这么看来是个很好的替代品

下一节打算好好总结下各个hooks api

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享