本文共 5138 字,大约阅读时间需要 17 分钟。
Redux 是一个独立的js状态管理库,非React内容之一
Redux本身是MVVM渐进式框架,M(数据模型) - V(视图) - VM(虚拟模型)
通常我们会把应用中的数据存储到一个对象树中 进行统一管理,我们把这个位置称为: state
这里需要注意的是,为了保证数据状态的可维护性和测试,不推荐直接修改state中的原数据
我们对state 的修改是通过reducer 纯函数来进行的,同时通过传入的 action 来执行具体的操作
action 是一个对象
type 属性: 表示要进行操作的动作类型, 增删改查。。。。
payload属性: 操作 state 的同时传入的数据
但是这里需要注意的是,我们不直接去调用Reducer函数,而是通过Store对象提供的dispatch方法来调用
单一数据源: 整个应用的state 被储存在一棵 object tree中,并且这个object tree 只存在于唯一的store中
State 是只读的,唯一改变state的方法就是触发 action,action是一个用于描述已发生事件的普通对象
使用纯函数来进行修改
npm i redux
import { createStore } from 'redux';
let store = createStore(reducer);
因为state的值可读不可写,所以需要一个纯函数去修改内部的值
这里给state加了默认值,可以不加function reducer(state = { name: "电影院", age: 20}, action) { return state;};
console.log(store);
dispatch: ƒ dispatch(action) —— 发起一次修改 (同步方法,立即执行)
action:{ type: "做了什么修改" --必填 }
getState: ƒ getState() —— 获取状态
replaceReducer: ƒ replaceReducer(nextReducer) —— 替换掉 reducer
subscribe: ƒ subscribe(listener) —— 监听状态的修改
console.log(store.getState());
浏览器反馈
使用dispatch
发起1次
修改后在获取状态
function reducer(state = { name: "电影院", age: 20}, action) { // 不加这行注释的话,switch...case 会提示不是期望默认值,不过不影响,加不加无所谓 // eslint-disable-next-line switch (action.type) { case 'edit_name': return { ...state, name: action.name } } return state;};...store.dispatch({ type: "edit_name", name: "健身房"});...console.log(store.getState());
浏览器反馈
dispatch
发起2次
修改后在获取状态 function reducer(state = { name: "电影院", age: 20}, action) { // 不加这行注释的话,switch...case 会提示不是期望默认值,不过不影响,加不加无所谓 // eslint-disable-next-line switch (action.type) { case 'edit_name': return { ...state, name: action.name }; case 'edit_age': return { ...state, age: action.age }; } return state;};...store.dispatch({ type: "edit_name", name: "健身房"});store.dispatch({ type: "edit_age", age: 2100});...console.log(store.getState());
浏览器反馈
dispatch
发起3次
修改且有一个是新属性
后在获取状态 function reducer(state = { name: "电影院", age: 20}, action) { // 不加这行注释的话,switch...case 会提示不是期望默认值,不过不影响,加不加无所谓 // eslint-disable-next-line switch (action.type) { case 'edit_name': return { ...state, name: action.name }; case 'edit_age': return { ...state, age: action.age }; case 'edit_time': return { ...state, time: action.time } } return state;};...store.dispatch({ type: "edit_name", name: "健身房"});store.dispatch({ type: "edit_age", age: 2100});store.dispatch({ type: "edit_time", time: '待定'});...console.log(store.getState());
浏览器反馈
state发送改变时触发
function reducer(state = { name: "电影院", age: 20}, action) { // 不加这行注释的话,switch...case 会提示不是期望默认值,不过不影响,加不加无所谓 // eslint-disable-next-line switch (action.type) { ... } return state;};store.subscribe(()=>{ console.log(store.getState());});store.dispatch({ ...});
浏览器反馈
我们上边已经使用了dispatch发起修改成功了,但是可以看出代码量是很多的,而且很庞大。
所以我们换一种写法import React from 'react';import { createStore, combineReducers } from 'redux';function index(state = { name: "首页" }, action) { // eslint-disable-next-line switch (action.type) { case 'edit_name': return { ...state, name: action.name } } return state}function list(state = { age: 20, time: "信息" }, action) { // eslint-disable-next-line switch (action.type) { case 'edit_age': return { ...state, age: action.age } case 'edit_time': return { ...state, time: action.time } } return state}function reducer(state = { }, action) { return { index: index(state.index, action), list: list(state.list, action) }}let store = createStore(reducer);store.subscribe(() => { console.log(store.getState())})store.dispatch({ type: "edit_name", name: "哈哈哈"})store.dispatch({ type: "edit_age", age: 2100})store.dispatch({ type: "edit_time", time: "待定"})function App() { return (123)}export default App
浏览器反馈
reducer
这个函数换成下边这种写法 let reducer = combineReducers({ index, list});
参数: 传入一个对象,这个对象的属性中,就是要合并的reducer
注意点: 对象的属性名,要和函数名相同
浏览器反馈
转载地址:http://rlwiz.baihongyu.com/