组件公共状态管理react-redux

Posted wj-goodgoodstudy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组件公共状态管理react-redux相关的知识,希望对你有一定的参考价值。

知乎日报项目中,公共状态使用了 redux 和 react-redux,记录学习的知识
redux 工程化其实就是按模块划分,在开发中能更好的理解和维护,因此该项目将状态管理划分为如下的模块:

  • store 用作存放状态管理的文件夹
  • action 是 store 中数据的来源,actions 文件夹用来管理派发行为对象的,index.js是将其他的 action 全部都合并到一个 action 中,并且暴露出去,该文件夹下其他的 js 文件都是针对不同功能的行为对象
  • reducer 文件夹是 reducer 的模块化管理,通过派发的不同行为对象标识(type)来执行不同的操作(状态处理函数),index.js是将 reducer 全都合并到一个 reducer 中,并且暴露出去
  • action-types.js 文件存放不同的行为对象标识符(type)
  • index.js 是用来创建并暴露 store
    下面为每个文件的具体代码
// store/actions/base.js
import * as TYPES from \'../action-types\';
import api from \'../../api\';
const baseAction = 
    // 异步获取登陆者信息,完成派发
    async queryUserInfoAsync() 
        let info = null;
        try 
            let  data, code  = await api.queryUserInfo();
            if (+code === 0) 
                info = data;
            
         catch (error)  
        return 
            type: TYPES.BASE_INFO,
            info
        
    ,
    // 清除存储的登录者信息
    clearUserInfo() 
        return 
            type: TYPES.BASE_INFO,
            info: null
        
    
;
// 暴露
export default baseAction;

⬆ 我们也可以看出其实action就是一个普通对象,只不过必须包含type标识符,同时需要有数据(可以从后端获取也可以接收传递的数据)传递给 reducer 进行处理

// store/actions/index.js
import baseAction from \'./base\';
import storeAction from \'./store\';

const actions = 
    base: baseAction,
    store: storeAction
;

export default actions;

⬆ 该文件用于整合所有的 action,进行统一暴露处理

// store/reducer/base.js
import * as TYPES from \'../action-types\';
import _ from \'../../assets/utils\';

let inital = 
    info: null

// 给state设置初始值
export default function baseReducer(state=inital,action) 
    // 因为 reducer 不能返回原来的对象,所以需要将对象进行克隆,因此在 case 中最好不要出现 push 等数组操作,因为并没有修改原来的对象或数组的地址,可以使用浅克隆...state,我这里使用了深克隆
    state=_.clone(state);
    // 使用 switch 语句进行逐个匹配
    switch(action.type)
        // 更新登陆者信息,在这里使用标识符进行匹配,减少错误,方便差错和维护
        case TYPES.BASE_INFO:
            state.info=action.info;
            break;
            // 也可以写成 return state.info=action.info;
        default:
    
    return state;
;

⬆ 对存储的状态进行处理

import  combineReducers  from \'redux\';
import baseReducer from \'./base\';
import storeReducer from \'./store\';
// 使用 combineReducers 将状态处理函数进行整合
const reducer = combineReducers(
    base:baseReducer,
    store:storeReducer
);
export default reducer;

⬆ 整合状态处理函数

// store/action-types.js
export const BASE_INFO = "BASE_INFO";

export const STORE_LIST = "STORE_LIST";

export const STORE_REMOVE = "STORE_REMOVE";

⬆ 定义对象标识符

import  createStore, applyMiddleware  from \'redux\';
import reduxLogger from \'redux-logger\';
import reduxThunk from \'redux-thunk\';
import reduxPromise from \'redux-promise\';
import reducer from \'./reducer\';
// 根据不同的环境使用不同的中间件,Thunk和Promise都是用于处理异步的状态
let middleware = [reduxThunk, reduxPromise],
    // 存放了当前的环境变量
    env = process.env.NODE_ENV;
// 如果当前环境为开发环境,就会有 reduxLogger,即每次状态改变都会打印路由状态信息
if (env === \'development\') 
    middleware.push(reduxLogger);

// 创建store并使用中间件
const store = createStore(
    reducer,
    applyMiddleware(...middleware)
);
export default store;

⬆ 查看当前环境变量 ⬇

⬇ reduxLogger 的提示

为了能在组件中都能实现数据共享,需要在 外嵌套 Provider

import  Provider  from \'react-redux\';
import store from \'./store\';
// ······其他配置项
const root = ReactDOM.createRoot(document.getElementById(\'root\'))
root.render(
    // ConfigProvider 是antd-mobile的配置项,用来配置语言选项
    <ConfigProvider local=zhCN>
        <Provider store=store>
            <App />
        </Provider>
    </ConfigProvider>
);

在需要使用store的组件中需要使用connect关键字,就可以在组建的props中获取需要的方法

import  connect  from "react-redux";
import actions from "../store/actions";

const Detail = function Detail(props) 
    console.log(props)
;
export default connect(
    state => 
        return 
            base: state.base,
            store: state.store
        
    ,
     ...actions.base, ...actions.store 
)(Detail);

props如下图 ⬇ :

    //  将所需的方法解构出来后就可以直接使用了
    let 
        base:  info: userInfo , queryUserInfoAsync,
        location,
        store:  list: storeList , queryStoreListAsync, removeStoreListById
     = props;
    useEffect(() => 
        (async () => 
            // 第一次渲染完,如果userInfo不存在,需要派发任务同步登陆者信息
            if (!userInfo) 
                let  info  = await queryUserInfoAsync();
                userInfo = info;
            
            // 已经登录 && 没有收藏列表
            if (userInfo && !storeList) 
                queryStoreListAsync();
            
        )();
    , []);

react-redux & 使用useSelector useDispatch 替代connect

 1.redux简介

  • redux是react全家桶的一员,它试图为 React 应用提供「可预测化的状态管理」机制。

  • Redux是将整个应用状态存储到到一个地方,称为store

  • 里面保存一棵状态树(state tree)

  • 组件可以派发(dispatch)行为(action)给store,而不是直接通知其它组件

  • 其它组件可以通过订阅store中的状态(state)来刷新自己的视图

2.redux核心

2.1 State

state是数据集合

可以理解为工厂加工商品所需的原材料

2.2 action

State的变化,会导致View的变化。但是,用户接触不到 State,只能接触到View 所以,State的变化必须是 View导致的。

action就是改变state的指令,有多少操作state的动作就会有多少action。

可以将action理解为描述发生了什么的指示器

2.3 reducer 加工函数

action发出命令后将state放入reucer加工函数中,返回新的state可以理解为加工的机器

2.4 store

store 可以理解为有多个加工机器的总工厂

let store = createStore(reducers);

Store 就是把它们联系到一起的对象。Store 有以下职责:

维持应用的 state;
提供 getState() 方法获取 state;
提供 dispatch(action) 方法更新 state;
通过 subscribe(listener) 注册监听器;
通过 subscribe(listener) 返回的函数注销监听器。

我们可以通过store.getState()来了解工厂中商品的状态, 使用store.dispatch发送action指令

 
 
 
 
 
 
 

参考:https://juejin.im/post/5af00705f265da0ba60fb844

以上是关于组件公共状态管理react-redux的主要内容,如果未能解决你的问题,请参考以下文章

深入理解Redux之手写React-Redux

React-Redux 总结

redux和React-Redux的基本使用

react-redux & 使用useSelector useDispatch 替代connect

react 中的 redux 和react-redux的区别分析

redux与react-redux