如何编写React Hooks风格的Redux组件

redux-react-hooks.png

Hooks特性在React的16.8版本被引入,在解决组件重用和生命周期逻辑破碎两大难题的同时,极大简化了组件写法,并且兼容旧写法,即使不想学也不要紧,向开发者释放了极大的善意。javascript

但是,组件写法的改变或多或少会让人有些顾虑,尤为是和第三方组件集成,开发社区中也出现了一些相似“Redux是否要被Hooks取代”的声音,就像以前的React Context特性出现的时候同样,大伙的第一反应老是先问Redux是否是要被取代了,即便二者之间并没有太多冲突,不过这也侧面反映了Redux框架在社区中的受众之广。html

实际上,React-Redux组件库做为粘合剂从7.1.0开始已支持Hooks特性,这让咱们写redux组件的时候再也不须要connect方法,咱们经过一个例子来展现如何写Hooks风格的redux组件。下面代码展现了一个复选框,使用了常见的connect方法将组件和store链接起来。java

import React, { Component } from "react";
import { connect } from "react-redux";
import { toggleSwitch } from "./UiReducer";

class Toggle extends Component {
  render() {
    const { ui, toggleSwitch } = this.props;
    return (
      <div>
        <div>{JSON.stringify(ui)}</div>
        <input
          type="checkbox"
          value={ui.toggle}
          onChange={toggleSwitch}
        />
      </div>
    );
  }
}

const mapStateToProps = ({ ui }) => ({
  ui
});

export default connect(
  mapStateToProps,
  { toggleSwitch }
)(Toggle);

最终效果以下:react

那么,接下来咱们尝试把这个组件重构成hooks风格的redux组件。typescript

第一步:重构成函数组件

用函数来代替class组件,而且咱们将ui和toggleSwitch从组件属性中解构出来,这一步相对简单,代码也获得了极大的缩减。redux

import React from "react";
import { connect } from "react-redux";
import { toggleSwitch } from "./UiReducer";

const Toggle = ({ ui, toggleSwitch }) => (
  <div>
    <div>{JSON.stringify(ui)}</div>
    <input type="checkbox" value={ui.toggle} onChange={toggleSwitch} />
  </div>
);

const mapStateToProps = ({ ui }) => ({
  ui
});

export default connect(
  mapStateToProps,
  { toggleSwitch }
)(Toggle);

第二步:使用useSelector

如今,咱们再也不使用connect方法,react-redux提供了useSeletor方法让咱们能够直接从hook中读取store的值。数组

import { connect, useSelector } from "react-redux";
const Toggle = ({ toggleSwitch }) => {
  const ui = useSelector(state => state.ui);
  return (
    <div>
      <div>{JSON.stringify(ui)}</div>
      <input type="checkbox" value={ui.toggle} onChange={toggleSwitch} />
    </div>
  );
};

第三步:使用useDispatch

像第二步同样,咱们能够直接经过hook获取到dispatch方法,而后根据须要执行自定义的action。框架

import { useSelector, useDispatch } from "react-redux";

...

const dispatch = useDispatch();

完成

最终,咱们的代码会被重构成下面这样:函数

import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { TOGGLE } from "./UiReducer";

const Toggle = () => {
  const ui = useSelector(state => state.ui);
  const dispatch = useDispatch();
  return (
    <div>
      <div>{JSON.stringify(ui)}</div>
      <input
        type="checkbox"
        value={ui.toggle}
        onChange={() => dispatch({ type: TOGGLE })}
      />
    </div>
  );
};

export default Toggle;

能够看到除了代码的简化外,相比较原connect写法,store中的值再也不从组件的属性传入,假如你使用typescript或flow,也省却了属性中对类型的声明,更进一步简化了组件写法,从这个示例中能明显感觉到Hooks带来的好处,也许,从如今开始就能够把connect方法扔掉了。ui

参考资料

Hooks-Intro

how to use redux with react hooks

公众号二维码.png

相关文章
相关标签/搜索