浅谈 React Hooks(一)

随着不久前 React@16.8.0 的发布,Hooks 也算是正式来到了幕前。我的以为对React来讲,Hooks 能够算是一个里程碑式的功能。本文不会详细介绍 Hooks,若是对 Hooks 还不是很了解的,能够先看下 Introducing Hooksjavascript

Hooks 带来了什么

简单来讲 Hooks 带来了能够在 Function Components 使用 state 和其它 React 特性的能力。而这带来的第一个很直观的好处就是原来写的 Function Components 由于需求变更须要增长 state 时,不再须要重构成 Class Components 了(重构再也不是火葬场了)。html

我的认为 Hooks 带来的最大益处就是可以帮咱们更好地组织业务代码,提升代码复用率。咱们经过一个例子来讲明,假设有这么一个需求:「组件须要根据浏览器宽度的变化,来显示不一样的内容」。java

咱们先用 Class Component 来实现:react

export default class ResizeClassComponent extends React.Component {
  constructor(props) {
    super(props);

    this.resizeHandler = null;
    this.state = {
      width: window.innerWidth,
    }
  }

  componentDidMount() {
    this.resizeHandler = () => {
      this.setState({
        width: window.innerWidth
      })
    }
    window.addEventListener('resize', this.resizeHandler);
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.resizeHandler);
  }

  render() {
    const { width } = this.state;
    return (
      <div>width: {width}</div>
    )
  }
}
复制代码

目前来看没什么问题,可是若是说如今又有一个组件须要实现这个功能,同样的代码再写一遍?那若是有不少组件都须要这个功能呢?每次都写一遍确定不现实,有人会说用render props或者高阶组件来处理这个问题,那就让咱们来实现一下:git

// render props
class ResizeRenderProps extends React.Component {
  constructor(props) {
    super(props);

    this.resizeHandler = null;
    this.state = {
      width: window.innerWidth,
    }
  }

  componentDidMount() {
    this.resizeHandler = () => {
      this.setState({
        width: window.innerWidth
      })
    }
    window.addEventListener('resize', this.resizeHandler);
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.resizeHandler);
  }

  render() {
    return this.props.children(this.state.width);
  }
}

export default class ResizeClassComponent extends React.Component {
  render() {
    return (
      <ResizeRenderProps> {width => <div>width: {width}</div>} </ResizeRenderProps>
    )
  }
}
复制代码
// 高阶组件
function withResize(WrappedComponent) {
  return class ResizeHoc extends React.Component {
    constructor(props) {
      super(props);

      this.resizeHandler = null;
      this.state = {
        width: window.innerWidth,
      }
    }

    componentDidMount() {
      this.resizeHandler = () => {
        this.setState({
          width: window.innerWidth
        })
      }
      window.addEventListener('resize', this.resizeHandler);
    }

    componentWillUnmount() {
      window.removeEventListener('resize', this.resizeHandler);
    }

    render() {
      return <WrappedComponent width={this.state.width} />; } } } export default withResize(class ResizeClassComponent extends React.Component { render() { return ( <div>width: {this.props.width}</div> ) } }) 复制代码

虽然实现了功能,可是两种方式都不可避免地对原来组件作了重构,而且增长了一个层级,若是用的多了就会致使「wrapper hell」,抛开这个不谈,render props高阶组件 自己自带的复杂度就不够友好。github

那么 Hooks 是怎么解决的呢?浏览器

import React, { useState, useEffect } from 'react';

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const resizeHandler = () => setWidth(window.innerWidth);
    window.addEventListener('resize', resizeHandler);
    return () => window.removeEventListener('resize', resizeHandler)
  })

  return width;
}

export default function ResizeHooks() {
  const width = useWindowWidth();
  return (
    <div>width: {width}</div>
  )
}
复制代码

是否是感受简单又清楚?只须要自定义一个 Hook(其实也就是一个普通的函数啦,只不过用了内置的几个Hook),使用的时候就像调用一个普通的函数同样,没有复杂的概念须要理解。正如前面所说,Hooks 能够帮助咱们组织代码,让相关性的代码都在一块,而不是像在 Class Components 里散落在各个生命周期函数中,贴个图方便理解:app

图片来源:twitter.com/prchdk/stat…函数

从图中能够发现逻辑相关的代码都被单独抽成了一个个 Hook,这意味着这部分有状态的逻辑(stateful logic)能够被复用,并且更容易理解。测试

稍微解释下什么叫「有状态的逻辑(stateful logic)」,这里的状态指的就是 React 的 state,对应的无状态的逻辑就是普通的函数啦。在 Hooks 以前,若是要复用这种有状态的逻辑,除了上述的 render props高阶组件以外就没有别的更简单直接的办法了。而有了 Hooks 以后,这部分逻辑可以被单独抽离出,职责更明确,从而使复用更加简单,代码更加清晰,并且也更便于测试。

尝试一下

不知道我说的这些有没有引发你对 Hooks 的兴趣呢?其实从 React 官方的态度能够看出是比较倾向于 Hooks 的,或者说是 Function Components,虽说是不会移除掉 Class Components(要是移除了,估计就炸了吧),可是能够在项目中先小范围试用下嘛,相信我你会喜欢上它的!

总结

前面写的有点分散,最后再总结一下 Hooks 带来的开发体验上的提高:

  • 想给 Function Components 增长 state 时,无需重构代码
  • 相比于render props高阶组件,提供了更简单直观复用有状态的逻辑(stateful logic)的方法
  • 代码逻辑更加统一,更容易组织代码结构
  • 便于测试

有了 Hooks 以后,Function Components 再也不是「高级字符串模版」啦!😝

以上只是我我的对 React Hooks 的一些想法,若有不对之处,欢迎指正~~

原文连接:github.com/sliwey/blog…

扩展阅读:

相关文章
相关标签/搜索