一文读懂React Hooks

612 阅读3分钟

这是我参与 8 月更文挑战的第 4 天,活动详情查看: 8月更文挑战

什么是React Hooks?

引自官网:

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

其实react一直是很推崇使用无副作用的function来实现组件的,class的组件弊端有很多,比如使用的模式是组合,而不是继承,违背了class的初衷,class有一定的上手门槛,而且内部的this会让一些新手摸不着头脑。

但是使用function的形式实现组件的话,会完全依赖外部状态,自身无法实现状态管理,这对于一些业务场景显得有些棘手。在这之前,我们会用redux或者把状态写在class内部来进行管理。在Hook出现后,可以可以在函数内部管理状态了。

解决了什么问题?

  1. 在组件之间复用状态逻辑很难
  2. 复杂组件变得难以理解
  3. 难以理解的 class

以上三点是官方提的,有兴趣的同学可以去看看官方怎么说的。我们可以这么看这个问题,一个视图的最终呈现需要UI+State,在传统的class组件中,UI和State是交织在一起的,想要抽离怎么办?一种是把一些状态提出来,封装成一个utils库,但是就进不了生命周期了,因为变成了静态方法。

Redux解决了这个问题,在引入Redux架构后,React Component负责UI的展示,Redux负责状态管理。

import React from 'react'
import { connect } from 'react-redux'
import { addTodo } from '../actions'

let AddTodo = ({ dispatch }) => {
  let input

  return (
    <div>
      <form
        onSubmit={e => {
          e.preventDefault()
          if (!input.value.trim()) {
            return
          }
          dispatch(addTodo(input.value))
          input.value = ''
        }}
      >
        <input
          ref={node => {
            input = node
          }}
        />
        <button type="submit">
          Add Todo
        </button>
      </form>
    </div>
  )
}
AddTodo = connect()(AddTodo)

export default AddTodo

Hooks 实践

useState

const [state, setState] = useState(initialState);

这个应该是我们用的最多的Hook了,在初始阶段,state的值会等于initialState,setState用于更新state的值,state发生改变,触发页面刷新。

useEffect

类似于在class组件中的componentDidMount、componentDidUpdate、componentWillUnmount的结合体,有两个参数,第一个参数为函数,第二个参数为依赖项

useEffect(
  () => {
    const subscription = props.source.subscribe();
    // 返回一个函数,会在销毁前调用
    return () => {
      subscription.unsubscribe();
    };
  },
  [props.source], // 根据依赖项的变化而触发函数的调用,传[]表示只调用一次
);

useContext

接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。一般我们会配合Context.Provider来使用。

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

小结

  • React Hooks 的出现提供了我们更好的模块化代码的方式,我们从以前的抽离公共UI的方式,可以变为更小粒度的拆分,例如拆分某个公共的逻辑
  • React Hooks 能够大大的减少我们大代码量,不需要再去理解复杂的class Component,一切都变的更加简单了
  • 在使用的过程中一定要注意到,Function Component 始终是函数,只要re-render,里面的代码都会重新执行,内联函数,内联对象都会被重新创建

最后打波小广告,美团校招社招内推,不限部门,不限岗位,不限投递数量,海量hc,快来快来~