数据流和数据流框架

1,数据流是行为与响应的抽象。

用户在页面上输入表单、按下按钮、拖拽等行为,页面会根据用户的行为给出一些响应,如刷新、跳转、局部刷新、Ajax局部刷新、数据更新等。以对象、方法来把它们抽象出来,这就是数据流。使用数据流可以帮助我们明确行为以及行为对应的响应。

 

2、React与数据流的关系

React是纯V的框架,只负责视图,把视图做成了组件化,不涉及任何的数据和控制,需要数据流进行支撑才能完成一个完整的前端项目。

 

3、主流的数据流框架:

1)FlUX基本概念:一种单项数据流或单向数据绑定的思想。

Flux将一个应用分成四个部分:

A、Dispatcher:所有的行为由一个统一的Dispatcher去分发,维持 Store 之间的依赖关系;

要把CounterStore 注册到全局唯一的 Dispatcher上去,Dispatcher 有一个函数叫做 register,接受一个回调函数作为参数,返回值是一个 token,这个 token 可以用于 Store 之间的同步。当通过 register 函数把一个回调函数注册到 Dispatcher 之后,所有派发给 Dispatcher的 action 对象,都会传递到这个回调函数中来

CounterStore.dispatchToken = AppDispatcher.register((action) => {

    if (action.type === ActionTypes.INCREMENT) {

        counterValues[action.value]++;

        CounterStore.emitChange();

    } else if (action.type === ActionTypes.DECREMENT) {

        counterValues[action.value]--;

        CounterStore.emitChange();

    }

});

 

B、Store:负责存储数据和处理数据相关逻辑,Store保持着数据,也保存着当前页面的状态, 根据用户的行为以及页面当前的状态。一个 Store 也是一个对象,这个对象存储应用状态,同时还要接受 Dispatcher 派发的动作,根据动作来决定是否要更新应用状态 。

用消息的方式建立Store和View的联系,让Store 扩展为EventEmitter对象,利用 EventEmitter的函数完成对Store状态更新的广播、添加监听函数和删除监听函数等操作 。

 

C、Action:驱动 Dispatcher 的 JavaScript 对象,代表一个动作的纯数据,不自带方法。作为管理, action 对象必须有一个名为 type 的字段,代表这个 action 对象的类型。定义 action 通常需要两个文件,一个定义 action 的类型,一个定义 action 的构造函数(也称为 action creator ),分成两个文件的主要原因是在 Store 中会根据 action 类型做不同操作,也就有单独导人 action 类型的需要。

export const increment = (counterCaption) => {

    AppDispatcher.dispatch({

        type: ActionTypes.INCREMENT,

        value: counterCaption

    })

};

 

D、View:视图部分,负责显示用户界面。存在于 Flux 框架中的 React 组件(view)需要实现以下几个功能:

创建时要读取Store上状态来初始化组件内部状态;

当Store上状态发生变化时,组件要立刻同步更新内部状态保持一致;

View 如果要改变 Store 状态,必须而且只能派发 action。

 

Flux优点: “单向数据流”的管理方式

在Flux的理念里,如果要改变界面,必须改变Store中的状态,如果要改变Store中的状态,必须派发一个action对象,追溯一个应用的逻辑很简单。

 

Flux的缺点:

(1)Store之间依赖关系:

在 Flux 的体系中,如果两个 Store 之间有逻辑依赖关系,就必须用上 Dispatcher 的 waitFor 函数。而dispatchToken的产生,是由Store 控制的, 虽然Flux解决了 Store 之间的依赖关系,但是明显的模块依赖并不好。

(2)难以进行服务器端渲染

在Flux的体系中,有一个全局的 Dispatcher,然后每一个Store都是一个全局唯一的对象,和一个浏览器网页只服务于一个用户不同,在服务器端要同时接受很多用户的请求,如果每个 Store 都是全局唯一的对象,那不同请求的状态肯定会混乱。

(3)Store 混杂了逻辑和状态

Store 封装了数据和处理数据的逻辑,但当我们需要动态替换一个Store的逻辑时只能把这个Store整体替换掉,那也就无法保持Store中存储的状态。

 

2)Redux(Reducer+Flux):

Redux适用场景:多交互、多数据源。

用户的使用方式复杂,不同身份的用户有不同的使用方式多个用户之间可以协作,与服务器大量交互,View要从多个来源获取数据

某个组件的状态,需要共享,某个状态需要在任何地方都可以拿到

一个组件需要改变全局状态,或者需要改变另一个组件的状态

 

Redux 的设计思想:

(1)Web 应用是一个状态机,视图与状态是一一对应的。

(2)所有的状态,保存在一个对象里面。

 

基本概念和 API

1、Store:保存数据的地方,整个应用只能有一个 Store。(createStore)

Store 允许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。

 

2、State:Store对象包含所有数据,时点的数据集合,就叫做State。一个State对应一个View。只要 State 相同,View 就相同。(store.getState())

 

3、Action:State的变化,会导致View的变化。但是,用户接触不到 State,只能接触到 View。所以,State的变化必须是View导致的。Action就是View 发出的通知,表示State应该要发生变化了,它会运送数据到Store。Action 是一个对象,其中的type属性是必须的。

store.dispatch()是 View 发出 Action 的唯一方法。

4、Reducer:Store收到 Action以后,必须给出一个新的 State,这样 View 才会发生变化,这种State的计算过程就叫做 Reducer。Reducer函数可以作为数组的reduce方法的参数,一系列 Action对象按照顺序作为一个数组。Reducer 函数最重要的特征是,它是一个纯函数。也就是说,只要是同样的输入,必定得到同样的输出。Reducer 函数里面不能改变 State,必须返回一个全新的对象。

Reducer接受 Action 和当前State作为参数,返回一个新的State:

const reducer = function (state, action) {

  return new_state;

};

store.dispatch方法会触发 Reducer 的自动执行。为此,Store 需要知道 Reducer 函数,做法就是在生成 Store 的时候,将 Reducer 传入createStore方法。

const store = createStore(reducer);

工作流程:

      A、首先,用户发出Action。store.dispatch(action);

      B、Store 自动调用 Reducer,并且传入两个参数:当前 State和收到的 Action,并会返回新的 State 。

                 let nextState = todoApp(previousState, action);

      C、State 一旦有变化,Store 就会调用监听函数。

                 store.subscribe(listener);

      D、listener可以通过store.getState()得到当前状态。如果使用的是 React,这时可以触发重新渲染 View。

         function listerner() {

            let newState = store.getState();

            component.setState(newState);  

         }

 

Redux的缺点:

  一个组件所有的数据,必须由父组件传过来,而不能像flux中直接从store取。

  当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新render,可能会有效率影响。

 

Redux的优点:

Redux不仅使我们能够以有条理的方式存储数据,而且使我们能够在应用的任何位置快速获取该数据。只需告诉Redux到底哪个组件需要哪个数据,它就会为你处理后续一切工作。

Redux的基本原则之一是存在单一数据源:Store。也就是说,Store包括应用的全局状态,全存储在一个对象树中。状态集中到一个位置后,调试和检测过程也会简单很多。

 

Flux和Redux的区别:

1、Redux 只有一个 store

Flux 里面会有多个 store 存储应用数据,并在 store 里面执行更新逻辑,当 store 变化的时候再通知 controller-view 更新自己的数据。

Redux 将各个 store 整合成一个完整的 store,并且可以根据这个 store 推导出应用完整的 state。同时 Redux 中更新的逻辑也不在 store 中执行而是放在 reducer 中。

2、没有 Dispatcher

Redux 中没有 Dispatcher 的概念,它使用 reducer 来进行事件的处理,reducer 是一个纯函数,这个函数被表述为(previousState, action) => newState,它根据应用的状态和当前的 action 推导出新的 state。

Redux 中有多个 reducer,每个 reducer 负责维护应用整体 state 树中的某一部分,多个 reducer 可以通过combineReducers方法合成一个根reducer,这个根reducer负责维护完整的 state,当一个 action 被发出,store 会调用 dispatch 方法向某个特定的 reducer 传递该 action,reducer 收到 action 之后执行对应的更新逻辑然后返回一个新的 state,state 的更新最终会传递到根reducer处,返回一个全新的完整的 state,然后传递给 view。

3、最大的区别就是对 store/reducer 的抽象

Flux 中 store 是各自为战的,每个 store 只对对应的 controller-view 负责,每次更新都只通知对应的 controller-view;而 Redux 中各子 reducer 都是由根reducer统一管理的,每个子reducer的变化都要经过根reducer的整合。

猜你喜欢

转载自blog.csdn.net/qq_30422457/article/details/81271686