React Hooks的999999个好处

林大夏 2019-12-09

最近前几个月开始,新项目都开始完全使用typescript+hooks,先不说typescript吧,hooks是真的香??

1.更好的分离页面和逻辑,重用逻辑的方法

现在前端项目的组件化,一般都是基于最基础的UI组件库(里面也有组件的功能逻辑),加上业务逻辑,封装一个个component,container。

组件是 UI + 逻辑的复用,但逻辑复用能力等于 0。

而在项目中,很难做到轻松的把 UI 和逻辑分开。(这里的逻辑并不是简单的能抽离的那种工具函数)。在此之前,React有Mixin(ES6Class就已经废弃了,不谈了),HOC,render props来抽离逻辑。

HOC

HOC并不是react提供的api,而是基于react特性的一种模式,常见的例子就是大家常见的react-redux中的connect函数,antd的form.create函数,HOC是一个函数,参数接受一个组件,返回一个新组件

render props

render props 我理解是平级组件之间单向依赖的一种模式,和HOC一样也不是什么react提供的api,也是一种模式,由React Trainning成员的一个大佬提出替代HOC的一种更好的模式。首先需要一个提供可变数据源的组件,然后给这个组件传入一个叫render函数的props(叫啥名字都行,提出者只是想强调这是一个拥有类似render功能的props..),特点就是这个props属性不是对象不是简单类型变量,就是一个函数,这个函数的参数就是希望用到可变数据源中的数据,返回结果就是一个jsx的UI结构。如果替代HOC,render的参数就可以是一个组件,react router4的withRouter即是这样实现:

import React from 'react'
import PropTypes from 'prop-types'
import hoistStatics from 'hoist-non-react-statics'
import Route from './Route'

/**
 * A public higher-order component to access the imperative API
 */
const withRouter = (Component) => {
  const C = (props) => {
    const { wrappedComponentRef, ...remainingProps } = props
    return (
      <Route render={routeComponentProps => (
        <Component {...remainingProps} {...routeComponentProps} ref={wrappedComponentRef}/>
      )}/>
    )
  }

  C.displayName = `withRouter(${Component.displayName || Component.name})`
  C.WrappedComponent = Component
  C.propTypes = {
    wrappedComponentRef: PropTypes.func
  }

  return hoistStatics(C, Component)
}

export default withRouter

仔细体会render props的用处和例子,可参考:1 2

hooks

HOOK是真正意义上的复用逻辑的武器。render props是把嵌套的HOC改成了一种平级传render函数的props的方法,但是当状态多个复用的时候,就也会变成不断嵌套的难看的结构。这里引用一下蚂蚁的一篇文章的例子:

<WindowSize>
  (size)=> (
        <Mouse>
        (position)=> <OurComponent size={size} mouse={position}/>
    </Mouse>
    )
</WindowSize>

又想监听size又想监听position,甚至还有scroll状态的时候。。。

使用react的hook模式,比如react-use库,我们只用一行代码就解决了:

const mousePosition = useMouse(ref);

且对typescript支持更好,我们可以在use函数中做类型校注。

参考:
react-use可看相关源码参考实现,秒啊
蚂蚁金服的文章
官方react自定义hook介绍

总的来说,hook目前还算完美干净的结局了逻辑重用的问题,把react组件化思想又深进了一步,且把页面与逻辑拆开也有利于代码的长期维护啦。

2.xxx 待更新喽 一大堆没时间写

相关推荐