Redux - javaScript状态管理器在React中的运用

Redux

官方链接https://www.redux.org.cn/
Redux 是一个独立的JavaScript 状态管理库,不属于React内容。
Redux 本身是 MVVM渐进式框架 M(数据模型) - V(视图) - VM(虚拟模型)

定义: 官方定义,是 JavaScript 状态容器,提供可预测化的状态管理。

作用及特点

  • 可以构建一致化的应用,
  • 运行于不同的环境(客户端、服务器、原生应用),
  • 易于测试
  • 提供超爽的开发体验,比如有一个时间旅行调试器可以编辑后实时预览。
  • 除了与React一起用之外,还支持其它界面库。
  • 体小精悍(只有2kB,包括依赖)。

Redus 三大原则

  • 单一数据源: 整个应用的state 被储存在一棵对象树中,并且这个对象只存在于唯一的store中
  • State 是只读的,通过触发 action去改变state(唯一方法),action是一个用于描述已发生事件的普通对象
  • 使用纯函数来进行修改

使用之前先安装(通过npm来安装)

npm i --save redux

store
负责存储的仓库,是一个对象
为了对 state, reducer, action,进行统一的管理和维护,我们需要创建一个Store对象(仓库)

import {createStore} from 'redux';
// createStore()创建一个仓库,仓库存储state,reducer管理员管理state
// 注意该方法中传入reducer函数体,不是函数的调用
let store = createStore(reducer);
console.log(store);

store对象提供的方法:

/* 
 * dispatch(action):发起一次修改(同步方法,会立即执行)
 *    --参数action 
 *      action:{type:"做了什么修改"}
 * 
 * subscribe(listener):监听状态的修改(每次state有修改,都会监听)
 * getState():获取状态
 * replaceReducer(nextReducer):替换掉reducer(不常用)
 * 
*/ 

state
数据存储到一个对象树中进行统一管理的位置成为state

注意:为了保证数据状态的可维护性和测试,不推荐直接修改state中的原数据,state是只读的。

修改 state
我们通过纯函数来对state修改,什么是纯函数?
纯函数是函数式编程的一种概念。

function reducer(state=默认值,action){return xx;}
 第一个参数(必需):state的初始值(数据)
 第二个参数(必需):action修改了什么
 return 返回值(必需)

纯函数特点如下:

  • 相同的输入永远返回相同的输出
  • 不修改函数的输入值
  • 不依赖外部环境状态
  • 无任何副作用 (如:异步请求以及定时器造成的问题)

使用纯函数的好处:

  • 便于测试
  • 有利于重构

reducer
reducer如同管理员,去管理store仓库中存储的state

function reducer(state={
  name:"React从初级到精通",
  price:59
  },action){
    //action是dispatch方法传过来的对象(即修改后的值返回的新对象)
    // switch做分类判断
    switch (action.type) {
      // 修改的name
      case 'new-name':
        // 当 state 变化时需要返回全新的对象,而不是修改传入的参数。
        return {
          // 解构state
          ...state,
          // name的新值
          name:action.name
        }

      // 修改的price
      case 'new-price':
        return {
          ...state,
          price:action.price
        }
    }
    return state;
}

action
通过reducer 纯函数来进行对state修改,同时通过传入的 action 来执行具体的操作

  • action 是一个对象
  • type 属性: 表示要进行操作的动作类型,如增删改查操作
  • payload属性: 操作 state 的同时传入的数据

注意:我们不直接去调用Reducer函数,而是通过Store对象提供的dispatch方法来调用

// 监听state状态
// 每次state修改都会触发该监听方法
store.subscribe(()=>{
  console.log(store.getState())
});

// 修改state状态
// 修改name
store.dispatch({
  type:"new-name",
  name:"HTML5全栈之路"
});

// 修改price
store.dispatch({
  type:"new-price",
  price:49
});

完整示例:

import React from 'react';
import {createStore} from 'redux';

function reducer(state={
    // 首页数据
    index:{name:"首页数据"},
    // 留言数据
    message:{name:"留言数据"},
    // 列表数据
    list:{name:"列表数据"}
},action){
    switch (action.type) {
        case "index":
            return {...state,index:action.index.name}
        case "message":
            return {...state,message:action.message.name}
        case "list":
            return {...state,list:action.list.name}
    }
    return state;
}
let store = createStore(reducer);

store.dispatch({
    type:"index_info",
    name:"首页"
})
store.dispatch({
    type:"message_info",
    name:"留言"
})
store.dispatch({
    type:"list_info",
    name:"列表"
})

function App() {
  return (
    <div className="App">
      <h2>hello,good morning</h2>
    </div>
  );
}

export default App;

从上例中,我们看到如果有多个页面需要管理时,都放在一个仓库中,一个管理员去管理时,
代码会显得很臃肿不清晰,还有别的办法可以处理吗?

当然有,我们可以将它们分别封装成函数,使用Redux提供combineRuders方法统一调用。

修改如下:

import {createStore,combineRuders} from 'redux';
//分别封装成函数,分别管理,相当于使用分管理员去管理,最后再主管理员reducer通过分管理员去统一管理
function index(state={info:"首页"},action){
    switch (action.type) {
        case "index_info":
            return {
                ...state,
                index:action.info
            }
    }
    return state;
}

function message(state={info:"留言"},action){
     switch (action.type) {
        case "message_info":
            return {
                ...state,
                message:action.info
            }
    }
    return state;
}

function list(state={info:"列表"},action){
     switch (action.type) {
        case "list_info":
            return {
                ...state,
                list:action.info
            }
    }
    return state;
}
// 手动合并
//function reducer(state={},action){
//    return {
//        index:index(state.index,action),
//        message:message(state.message,action),
//        list:list(state.list,action)
//    }
//}

// 使用Redux提供的combineReducers()方法来合并
let reducer = combineReducers({
    // 给该方法传入一个对象作为参数,这个对象的属性就是要合并的reducer,
    // 对象的属性名:函数名
    // 这里的对象的属性名与函数名一致,只写一个就可以
    index,
    message,
    list
});

// 创建仓库
let store = createStore(reducer);

// 监听state
store.subscribe(()=>{
    console.log(store.getState());
});

// 修改state
store.dispatch({
    type:"index_info",
    info:"我是首页内容"
});
store.dispatch({
    type:"message_info",
    info:"我是留言内容"
});
store.dispatch({
    type:"list_info",
    info:"我是列表内容"
});

Redux - javaScript状态管理器在React中的运用_第1张图片
如图,store的subscribe()方法在每次state修改时都会去监听,控制台输出了每次监听到的修改的结果。

你可能感兴趣的:(Redux,React,Redux,React,createStore,subscribe,dispatch)