Redux-ORM明白之完成Todo List

Redux-ORM明白之完成Todo List

一、观点

  • redux-orm及其作用:

redux-orm主假如用来治理我们的state数据,当一个项目比较大,逻辑构造比较复杂,每一个数据之间都有联络,此时便须要将这些state举行统一治理,redux-orm就是用来处理这些数据间的关联题目,所以redux-orm就像一个关联型数据库,而每一个对象范例就像是数据库中的数据表,而且是以JavaScript的对象情势存储这些数据的。
那末也就是说,当项目的中涉及到的对象范例并不许多,且对象范例之间的关联性不大的时刻,并不发起运用redux-orm,假如项目充足简朴,连redux也不须要运用到。

二、完成Todo List及代码剖析

1、剖析实例及行动

在todo list 完成的基本功用有:
挑选用户
竖立todo
标记todo完成
删除todo
竖立tag标签
移除tag标签
所以根据上面的功用,能够将todo list分为三张表,分别是user(用户表)、todo表和tag标签表,这些表就相当于一个实例,每一个实例都邑有本身的行动属性和要领

  • User:

属性:id、 name
行动:selectUser

  • Todo:

属性:id、text(todo内容)、done(标记完毕)、user、 tags
行动: createTodo、markDone、deleteTodo

  • Tag:

属性: name
行动: addTagToTodo、 removeTagFromTodo

2、竖立state

State是一个对象,是用来形貌运用。在这个todo list中,当须要有一个对象用来形貌

3、Action竖立函数

Action是把数据从运用传到store的有用载荷,它是store数据的唯一泉源。其本质上是JavaScript一般对象,action内必需运用type字符串范例,type示意将要实行的行动,在多半情况下,type被已定义为字符串常量。
Action竖立函数就是天生action要领,该要领只是简朴的返回一个action。比方,关于增添标签这个action是如许实行的,先竖立一个addTagToTodo的要领,该要领吸收tag和todo两个参数,然后将其返回为一个对象,个中对象的属性值中必需有一个type

export const addTagToTodo = (todo, tag) => {
    return {
        type: ADD_TAG_TO_TODO,
        payload: {
            todo,
            tag,
        },
    };
};
4、构建数据表并关联

在ORM中定义了一个Model类来将实体类关联起来, 关于Todo这个实体类来讲,经由过程ES6类语法举行定义,并继续了ORM的Model类。
Model须要设置称号才能够识别到对应的数据,以及实体类与其他数据关联的体式格局。
关于Todo类来讲,它跟User只能是一对多,一个User下有多个Todo,而跟tag能够多对多,一个Todo能够有多个tag,通用一个tag能够存在在多个Todo中,所以Model类中的fields主假如用了来定义当前实体类与其他类的关联关联,这些如:fkmanyoneToOne吸收两个参数,第一个是被关联的实体类,就是在Model中定义的modelName和操纵的类名。 而且关联关联只须要定义一次就能够了,不须要反复定义。
末了要完成实体类间的关联必需将其注册到Schema()要领中并导出,如许才能够真正关联其实体间的关联。当实体类比较多的情况下,能够须要一个零丁的文件来寄存这些须要注册的实体类,如许能够使项目模块化更易于治理。

import { Schema, Model, many, fk } from 'redux-orm';
import {
    CREATE_TODO,
    MARK_DONE,
    DELETE_TODO,
    ADD_TAG_TO_TODO,
    REMOVE_TAG_FROM_TODO,
} from './actions';   

export class Todo extends Model {
    static reducer(state, action, Todo, session) {
        const { payload, type } = action;
        switch (type) {
        case CREATE_TODO:
            const tagIds = action.payload.tags.split(',').map(str => str.trim());
            const props = Object.assign({}, payload, { tags: tagIds, done: false });
            Todo.create(props);
            break;
        case MARK_DONE:
            Todo.withId(payload).done = true;
            break;
        case DELETE_TODO:
            Todo.withId(payload).delete();
            break;
        case ADD_TAG_TO_TODO:
            Todo.withId(payload.todo).tags.add(payload.tag);
            break;
        case REMOVE_TAG_FROM_TODO:
            Todo.withId(payload.todo).tags.remove(payload.tag);
            break;
        }
    }
}
Todo.modelName = 'Todo';
Todo.fields = {
    tags: many('Tag', 'todos'),
    user: fk('User', 'todos'),
};

export const schema = new Schema();
schema.register(Todo);

export default schema;
5、更新状况

Reducers主假如用来更新state,相应actions并发送到store的援用状况变化。
在Redux运用中,一切的state都被保留在一个单一对象中。
reducer是一个纯函数,吸收旧的state和action,返回新的state。不能够在reducer中通报参数、实行有副作用的操纵以及挪用非纯函数。只需纯真地实行盘算就能够,其更新是部分的,只需当当前的reducer中的数据发作转变后,reducer才会从新举行盘算。
在Redux-ORM中运用特定reducers的模子来操纵数据。起首在Model类中先定义一个静态的reducer要领,它会吸收一切须要更新的action。假如没有定义reducers的话,ORM会直接运用默许要领去完成更新。
其道理是,在静态的reducer要领中吸收四个参数:state(状况)、action(当前操纵)、Todo(模子类)、session(ORM的会话实例)。在Todo的reducer中,经由过程对当前Todo的type举行轮回遍向来实行对Todo的增添、删除、修正等操纵,而session这个会话实例参数主假如用来接见和查询其他Model,然则不发起在当前的Model修正其他Model中的数据。

6、数据的挑选

在Redux-ORM中的seletors是运用了了第三方插件reselect
selector在ORM中能够盘算派生数据,其在全部ORM中一直是有用的,跟reducer一样,只需其吸收的参数发作转变就会触发该要领,而且selector是可组合的,能够作为其他seletor的输入

export const todos = createSelector(
    ormSelector,
    state => state.selectedUserId,
    schema.createSelector((orm, userId) => {
        return orm.Todo.withRefs.filter({ user: userId }).map(todo => {
            const obj = Object.assign({}, todo.ref);
            obj.tags = todo.tags.withRefs.map(tag => tag.name);
            return obj;
        });
    })
);  

起首运用createSelector要领竖立了todo的挑选器,该要领中的第一个参数始终是orm的selector,然后对input selector举行回调,回调是用过schema竖立了createSelector要领来盘算关联的数据然后并返回。
在todo的seletor中,经由过程与selectedUserId中举行关联,当被选中的userId发作变化时就会触发该要领,并过滤出该user下的一切Todo数据及该Todo下的tag数据并返回。

7、运用在视图中

当我们将一切的数据都定义好了以后,就须要在视图中去运用
起首,在进口文件导入redux中的createStore、combineReducers、applyMiddleware、Provider另有redux中的createLogger等要领
createStore:该函数主假如用来天生store, store就是保留数据的处所,相当于一个容器,全部项目中只能有一个store
combineReducer:主假如用于Reducer的拆分,其能够将拆分的各个子reducer函数经由过程该要领合成一个大的Reducer
applyMiddlewarecreateLogger都是redux的中间件,主假如用来实行异步操纵。个中createLoggerredux-logger模块中的要领,是天生redux日记,并打印在控制台,该要领是放在applyMiddleware要领中。
Provider: 主假如让Store容器组件拿到state。
末了,能够运用redux中的connect()要领将UI组件和store容器组件连接起来,重要依托输入与输出来完成。
输入(mapStateToProps)是将store中的数组转化为UI组件的参数。 其是一个函数,竖立一个从state对象到UI组件props对象的映照关联,其实行后返回一个对象,内里的每一个键值对就是一个映照
输出(mapDispatchToProps)是用户发出的行动转变成Action对象,从UI组件传出去。它定义哪些用户的操纵应当当作Action并传给Store,它个能够是一个函数,也能够是一个对象。

    原文作者:husky0601
    原文地址: https://segmentfault.com/a/1190000015804409
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞