Flux流程

单向数据流是Flux的核心。而早些时候我们接触过的MVC架构的数据流是双向的。controllermodelview之间交互的媒介,它处理view的交互操作,通知model进行更新,同时在操作成功后通知view更新。

图片

  • Action

Action就是用来描述一个行为的对象,里面有相关的信息,比如说一个创建文章的Action可以是{ actionName: 'create-post', data: {content: 'new stuff'} }

  • Dispatcher

Dispatcher是一个信息的分发中心,它也是ActionStore的连接中心,Dispatcher可以使用dispatch方法执行一个Action,并且可以用register方法注册回调,在回调方法中处理Store内容

  • Store

Store处理完毕之后,它可以使用emit方法向其他地方发送命名为change的广播,告诉它们Store已经发生变更

  • View

View层坚挺这次change事件,一旦change事件被触发,那么该层就可以调用setState来更新整个UI

Redux流程

Redux使用了类似于Flux的单向数据流,但是它只有一个单一的store对象,而且Redux中没有Dispatcher。当action需要被执行的时候,store提供的dispatch方法会被执行,将action以及state作为参数,返回新的state

图片

Redux中文文档:http://cn.redux.js.org/
Redux英文原版:http://redux.js.org/

流程有以下几步:

  • action

action是信息的载体,里面有action的名称和要传递的信息,然后可以被传递到store中去。

// 对action命名
const CREATE_POST = 'CREATE_POST';
const DELETE_POST = 'DELETE_POST';
const USER_LOGIN = 'USER_LOGIN';


// 构造action creator,用来创建不同的action
function createPost(data) {
    return {
        type: CREATE_POST,
        data: data
    }
}

function deletePost(data) {
    return {
        type: DELETE_POST,
        data: data
    }
}

function userLogin(data) {
    return {
        type: USER_LOGIN,
        data: data
    }
}


Flux中,一个action creator不会返回一个action,通常是调用Dispatcherdispatch方法。

import AppDispatcher from '../dispatcher/AppDispatcher';

const TodoAction = {
    create(data) {
          AppDispatcher.dispatch({
              actionType: 'CREATE_POST',
              data
        });
    },
    delete(data) {
          AppDispatcher.dispatch({
              actionType: 'DELETE_POST',
              data
        });
    }
};

export default TodoAction;
  • reducer

action定义了要执行的操作,但是没有规定state如何变化,reducer的任务就定义整个程序state如何变化。

Redux中,整个程序的所有数据存储在一个唯一一个Object中。这是Redux不同于Flux的一个重要特性,Flux可以有多个store来处理不同类型的数据,而Redux整个应用程序的state都在一个单独的Object中。

// 将最初的结构分解为两个分离的state
const initalPostStates = [];
const initalUserStates = {
    isLogin: false,
    userData: {

    }
}

function posts(state = initalPostStates, action) {
    switch(action.type) {
        case CREATE_POST:
            return [...state, action.data];
        case DELETE_POST:
            return state.filter((post) => {
                return post.id != action.id
            });
        default:
            return state;
    }
}

function user(state = initalUserStates, action) {
    switch(action.type) {
        case USER_LOGIN:
            return Object.assign({}, state, {
                isLogin: true,
                userData: action.data
            });
        default:
            return state;
    }
}

特别注意:不能改变state值。在上面函数中,每次返回的都是全新的对象,而不是直接改变state值。

合并reducer

// 将两个reducer合并
function rootReducer(state = initalState, action) {
    return: {
        posts: posts(state.posts, action)
        user: user(state.user, action)
    };
}

// Redux提供来一个函数用来合并
import { combineReducers } from 'redux';

const rootReducer = combineReducers({
    posts,
    user
});

  • store

store其实是actionreducer的粘合剂,完成以下任务:

  • 保存整个程序的state

  • 通过getState()方法访问state的值

  • 通过dispatch()方法执行一个action

  • 通过subscribe()方法注册回调,监听state的变化

import { createStore } from 'redux';

// 创建store,以reducer这个纯函数作为参数
let store = createStore(rootReducer);

流程大概分为以下几步:

  • 调用store.dispatch(action)来执行一个action

  • store调用传入的reducer函数处理action

  • reducer处理action并返回新的state

  • store保存reducer返回的完整state,可以根据store.getState()获取当前state,也可以通过store.subscribe(listener)来监听state的变化