redux是一种状态容器。
因为用了reducer和纯函数所以可预测,每个state都由旧的state建立一个新的state。
redux严格限制数据只能一个方向上流动。
要说明整个模型的运作流程,首先要弄清redux模型中几个组成对象:action,reducer,store。
action把数据从ui传到store,store数据的唯一来源,要改变组件状态,就要分发action。
reducer reducer通过action的type来处理不同的事件
store 状态树,保存所有对象状态。
不管什么应用程序都需要有App state(应用程序状态),不论是在一个需要用户登录的应用,要有全局的记录着用户登录的状态,或是在应用程序中不同操作介面(组件)或各种功能上的数据沟通,都需要用到它。
属性React.js的同学都知道,React被设计为一个MVC架构中的View(视图)的函数库,但实际上它可以作的事情比MVC中的View(视图)还要更多,它甚至可以作类似Model(模型)或Controller(控制器)的事情。
同时,在React中的组件是无法直接更动state(状态)的包含值,要透过setState方法来进行更动,这有很大的原因是为了Virtual DOM(虚拟DOM)的所设计,这是其中一点。另外在组件的树状阶层结构,父组件(拥有者)与子组件(被拥有者)的关系上,子组件是只能由父组件以props(属性)来传递属性值,子组件自己本身无法更改自己的props,这也是为什么一开始在学习React时,都会看到大部份的例子只有在最上层的组件有state,而且都是由它来负责进行当数据改变时的重新渲染工作,子组件通常只有负责呈现数据。
当然,有一个很技巧性的方式,是把父组件中的方法声明由props传递给子组件,然后在子组件触发事件时,调用这个父组件的方法,以此来达到子组件对父组件的沟通,间接来更动父组件中的state。不过这个作法并不直觉,需要事先规范好两边的方法。在简单的应用程序中,这沟通方式还可行,但如果是在有复杂的组件嵌套阶层结构时,例如层级很多或是不同树状结构中的子组件要互相沟通时,这个作法是派不上用场的。
在复杂的组件树状结构时,唯一能作的方式,就是要将整个应用程序的数据整合在一起,然后独立出来,也就是整个应用程序领域的数据部份。另外还需要对于数据的所有更动方式,也要独立出来。这两者组合在一起,就是称之为”应用程序领域的状态”,为了区分组件中的状态(state),这个作为应用程序领域的持久性数据集合,会被称为store(存储)。
import { createStore } from 'redux'
const reducer = function(state,action){
return state
}
const store = createStore(reducer)
从redux中引入createStore()
创建一个reducer的方法,第一个参数state是保存在store中的数据,第二个参数action是一个容器,用于:
type:一个简单的字符串常量 add update delete
payload:用于更新状态的数据创建一个redux存储区,以reducer作为参数来构建,存储在redux中的数据可以直接访问,但是只能通过提供reducer进行更新。
多个reducer
import {createStore} from 'redux'
import {combineReducers} from 'redux'
const productsReducer = funtion(state=[],action){
return state
}
const cartReducer = funtion(state=[],action){
return state
}
const allReducers = {
products: productsReducer,
cart: cartReducer
}
const rootReducer = combineReducers(allReducers)
let store = createStore(rootReducer);
把数据插入到state中,作为初始数据,我们可以在reducer中进行操作,return中添加数据
const initialState = {
cart:[
{
product:'bread',
quantity:2,
unitCost:90
},
{
product:'milk',
quantity:1,
unitCost:47
}
]
}
const cartReducer = funtion(state=initialState,action){
switch (action.type) {
case ADD_TO_CART: {
return {
...state,
cart: [...state.cart, action.payload]
}
}
default:
return state;
}
}
一个reducer处理不同action类型,但处理的是同一个数据,因此我们需要一个switch语句,比如增删改查就可以使用。
所以我们需要定义一个action,作为store.dispacth的参数,action返回两个属性:必选的type和可选的payload。payload就是传给reducer的数据
function addToCart(product,quanlity,unitCost){
return {
type:ADD_TO_CART,
payload:{product,quanlity,unitCost}
}
}
然后,我们定义了一个函数,返回一个JavaScript对象。在我们分发消息之前,我们添加一些代码,让我们能够监听store事件的更改。dispacth分发消息,接收的是action,也就是将action 触发,然后action再return type 和payload,然后reducer再switch,返回state
let unsubscribe = store.subscribe(() =>
console.log(store.getState())
);
store.dispacth(addToCart('Coffee 500gm', 1, 250))
unsubscribe();
纯属笔记,建议参考:https://blog.csdn.net/xiangzhihong8/article/details/80518709