4

react hooks: 像组件state一样使用redux

 3 years ago
source link: https://zhuanlan.zhihu.com/p/60405093
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

react hooks: 像组件state一样使用redux

字节跳动 前端工程师

redux与react结合使用一直是:利用HOC通过props向组件注入数据。这种包装模式达到了很好的逻辑复用与解耦。但随着react hooks出现,一种新的redux与react的结合使用方式诞生了。

摘抄一段官网上的话:

React doesn’t offer a way to “attach” reusable behavior to a component (for example, connecting it to a store). If you’ve worked with React for a while, you may be familiar with patterns like render props and higher-order components that try to solve this. But these patterns require you to restructure your components when you use them, which can be cumbersome and make code harder to follow. If you look at a typical React application in React DevTools, you will likely find a “wrapper hell” of components surrounded by layers of providers, consumers, higher-order components, render props, and other abstractions. While we could filter them out in DevTools, this points to a deeper underlying problem: React needs a better primitive for sharing stateful logic.
With Hooks, you can extract stateful logic from a component so it can be tested independently and reused. Hooks allow you to reuse stateful logic without changing your component hierarchy. This makes it easy to share Hooks among many components or with the community.

大致意思是:react hooks能够在不改变组件的层级达到和render props以及HOC一样的效果,而且更简单。

这里我们就要用自定义hook来替换react与redux连接的这部分HOC,额外的会做一些符合hook风格的改变。

我们以写一个简单计数器为栗,效果如下:

v2-dd37a1a81801ab370492dd834d284797_b.jpg
点击-就减一,点击+就加一

先来看使用HOC的方式实现(以dva举栗)

日常开发中经常使用dva,很好的redux封装库

这是model:

const model = {
  namespace: "count",
  state: 0,
  reducers: {
    add(state, { type, payload }) {
      return state + 1;
    },
    minus(state, { type, payload }) {
      return state - 1;
    }
  }
};
export default model;

这是业务逻辑代码:

import React, { Fragment } from "react";
import { connect } from "dva-no-router";

const Demo = props => {
  const handleAdd = e => {
    const { dispatch } = props;
    dispatch({
      type: "count/add"
    });
  };
  const handleMinus = e => {
    const { dispatch } = props;
    dispatch({
      type: "count/minus"
    });
  };
  return (
    <Fragment>
      <h2>{props.count}</h2>
      <section>
        <button onClick={handleAdd}>+</button>
        <button onClick={handleMinus}>-</button>
      </section>
    </Fragment>
  );
};

const mapStateToProps = state => {
  const { count } = state;
  return {
    count
  };
};
export default connect(mapStateToProps)(Demo);

完整栗子在线地址请戳这里

这个栗子虽然没有异步代码,但是不影响说明redux整体的使用风格。

再来看看用自定义hook重写该栗子的代码

这是model:

import { gluer } from "react-glue-redux-hook";

const count = gluer((data, state) => {
  return state + data;
}, 0);

export default count;

做了一些改变,看上去更像react hooks的风格。(userReducer传送门

这是store:

import { createStore, combineReducers } from "redux";
import { destruct } from "react-glue-redux-hook";
import count from "./Count/model";

const store = createStore(() => ({}));
const modelSchemas = {
  count
};
const { reducers, useGlue } = destruct(store)(modelSchemas);

store.replaceReducer(combineReducers(reducers));

export { useGlue, modelSchemas };
export default store;

这是业务逻辑代码:

import React, { Fragment } from "react";
import { modelSchemas, useGlue } from "../store";

const Demo = props => {
  const [count] = useGlue(modelSchemas.count);
  const handleAdd = e => {
    modelSchemas.count(1);
  };
  const handleMinus = e => {
    modelSchemas.count(-1);
  };
  return (
    <Fragment>
      <h2>{count}</h2>
      <section>
        <button onClick={handleAdd}>+</button>
        <button onClick={handleMinus}>-</button>
      </section>
    </Fragment>
  );
};

export default Demo;

完整栗子在线地址请戳这里

两个栗子都实现的相同计数功能,两者的风格大不相同。

上面栗子说明:使用自定义hook能很好的将redux与react链接部分的逻辑进行复用。随着react hooks逐渐在react占据主流,这类自定义hook或者说函数的使用会是一种趋势。

更多请看:react-glue-redux-hookglue-redux基于redux运行时的数据模型


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK