Skip to content

状态管理 — 唐刀

ruifengwei edited this page Jun 11, 2020 · 2 revisions

背景

在没有唐刀之前,猫眼 react 应用的状态管理方案没有统一的解决方案,主要分为 reduxdva,但二者并没有极致地提高我们的开发效率。 为了高效率地管理应用状态,打造符合猫眼业务特色的状态管理方案,于是便有了唐刀的诞生。

为什么需要状态管理? 众所周知,React 应用是由一个个状态机组合而成, 组件是 React 应用的核心,状态则是一个或者多个组件的灵魂。对于一个成型的 React 应用来说,组件构成了应用的骨架,而状态则是贯通全身的血液是应用充满活力和生机的关键。随着应用的复杂化,要准确区分哪些组件需要状态将是一件无比困难的事情。如果将所有状态都存放在根组件,通过 context api 来消费状态未免不是一种简单的方法。但这并不能有效地解决问题,因为我们不仅需要通过 setState 细粒度控制状态变化,还要设计各组件间的状态通信。一旦设计不好,状态的管理可能会变得混乱,状态的变化也会因为无迹可查而变得不可预测。 详细可以阅读: Redux 状态管理框架演进之路

简介

唐刀是基于 redux + redux-saga + react-router 应用架构的上层封装,是基于猫眼已有的 react 状态管理方案的最佳实践。

唐刀更多细节,请点 这里 唐刀github :github-tangdao 唐刀npm:npm-tangdao

简单容易好上手

唐刀整体上的上手和学习成本极低,哪怕你不了解 reduxredux-saga 你也可以轻松上手使用,绝对是你的趁手兵器。简单上手

快速上手

下面通过一个简单的计数应用,来看一下唐刀的使用。

第一步:创建 model

model 是唐刀的核心,负责管理状态的变化,一个应用的状态可以由多个 model 组成,分别管理一部分状态。

简单的 model 对象由以下几个属性构成:

  • namespace:model 的命名空间,也是 model 在全局 state 上的属性
  • state:初始状态值
  • reducers:定义改变 state 的处理方法,不可以处理异步任务
  • effects:处理异步任务,可以通过 call 执行异步请求,通过 put 执行状态的改变
// models/count.js

const count = {
    namespace: 'count',
    state: 0,
    reducers: {
        add(state, { payload }) {
            return state + payload
        }
    },
    effects: {
        * asyncAdd({ payload }, { put, call }, actionCreator) {
            yield call(delay, 3000);
            yield put(actionCreator.add(payload))
        }
    }
}

export default count;

关于 model 更多的细节,可以点这里

第二步:创建视图组件

// pages/app

import React from 'react';
import { connect, dispatch } from '@myfe/tangdao';

function App(props) {
    const { count } = props;
    return (
        <div>
            count: {count}
            <button onClick={() => {dispatch.count.add(1)}}>Add</button>
            <button onClick={() => {dispatch.count.asyncAdd(1)}}>asyncAdd</button>
        </div>
    )
}
export default connect(state => {
    return {
        count: state.count
    }
})(App);

第三步:创建应用

import React from 'react';
import tangdao, { loading } from '@myfe/tangdao';
import count from './models/count';

// 第一步 创建唐刀实例
const td = tangdao();

// 第二步 使用插件
td.use(loading());

// 第三步 注册 model
td.model(count);

// 第四步 挂载路由 or 组件
td.router(require('./pages/App').default);

// 第五步 启动应用
td.start('#app');

Clone this wiki locally