如何編寫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

相關文章
相關標籤/搜索