Redux是一个非常有用的框架,他主要解决状态的统一管理问题。而React则将所有组件视为状态机,所以Redux可以看作是一个React的数据管理中心。但需要注意,并不是必须用Redux来管理数据,只是该框架让复杂业务逻辑和多组件通信更加方便。
Redux的思想主要概括为下面2点:
a.Web 应用是一个状态机,视图与状态是一一对应的。
b.所有的状态,保存在一个store对象里面。
这样state就是一个单一的对象,所有的状态数据都维护在一颗状态树中,服务端很容易初始化状态,state则只能通过dispath(action)来触发更新,更新逻辑由reducer执行。
Store
store是一个存储对象,保存着所有的数据,整个应用只有唯一一个Store对象。
Redux提供了createStore(fn)来生成一个Store对象
import { createStore } from 'redux';
const store = createStore(fn);
store.getState():获取当前状态
store.dispatch(action):用于触发state更新,将action发出。
store.subscribe(lister):用于注册state变化监听器,返回一个函数,调用该函数则解除监听器。
createStore(reducer,[initalState]):创建Store对象
State
Store对象包含所有数据,如果想得到某个时点的数据,就需要对Store生成快照,而生成的快照数据集合就叫做State。当前时刻的State可以通过store.getState()得到。
import { createStore } from 'redux';
const store = createStore(fn);
const state = store.getState();
Action
状态的改变将会导致视图的变化,但是用户只能操作视图,所以必须让视图的操作来影响状态的改变,Action的作用就是通知视图操作了,状态也应该做相应的改变来渲染视图操作的效果。
Action是一个对象,该对象有如下属性:
type:action的名称,通常是字符串常量或者符号,必须。
payload:携带的信息,任何类型的值,可选。如果error为true则payload是一个错误对象。
error:操作错误标识,任何类型的值,可选。
meta:payload外的其他信息,任何类型的值,可选。
const actionName = "Redux test";
function addAction(text){
return {
type:actionName,
payload:text
}
}
const newAction = addAction("Learn Redux");
Reducer
Store接收到Action以后,必须返回一个新的State,这样视图才会重新渲染,计算新的State的过程叫做Reducer。
Reducer是一个函数,接受2个参数,当前的state和action,返回一个新的state。
const reducer = function (state, action) {
// ...
return new_state;
};
redux的工作原理:
1.首先定义好组件;
2.在组件触发事件中调用stroe.dispatch(action),发出action,自动执行Reducer函数;
3.定义好Reducer对象来处理组件发出的action;
4.根据定义的Reducer对象创建store对象;
5.创建监听器,在store改变后重新渲染界面。store.subscribe(lister)
简易流程
component --> dispatch(action) --> reducer --> subscribe --> getState --> component
示例
import {createStore} from 'redux';
import React from 'react';
import ReactDOM from 'react-dom';
let countReducer = (state=0,action) => {//第二步:定义Reducer执行函数
switch(action.type){
case "add":
state += 1;
break;
case "substrat":
state -= 1;
break;
default:
break
}
return state;
}
let store = createStore(countReducer);//第三步:创建Store对象
let addCount = ()=>{//加法操作
store.dispatch({
type:"add",
payload:"每次加1"
})
}
let subStractCount= () => {//减法操作
store.dispatch({
type:"substrat",
payload:"每次减1"
})
}
const render = () => {
ReactDOM.render(//第一步:定义组件,getState()本为第五步,这里未做区分
{store.getState()}
,
document.getElementById("redux")
)
}
store.subscribe(render)//第四步:创建监听器,监听到状态修改后就重新渲染界面
render()//初始化渲染
效果图:
点击+号,数字加1,点击-号,数字减一。