首页 > 其他分享 >组件公共状态管理react-redux

组件公共状态管理react-redux

时间:2023-04-12 23:56:36浏览次数:39  
标签:info reducer react action 组件 import redux store

知乎日报项目中,公共状态使用了 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();
            }
        })();
    }, []);

标签:info,reducer,react,action,组件,import,redux,store
From: https://www.cnblogs.com/wj-goodgoodstudy/p/17311112.html

相关文章

  • Vue.js 两个新的生命周期钩子(路由组件独有)
    视频11.两个新的生命周期钩子作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。具体名字:activated路由组件被激活时触发。deactivated路由组件失活时触发。>Home.vueNews.vuecomponentsBanner.vue<template> <divclass="col-xs-offset-2col-xs-8"> ......
  • 如何在2023年学习React
    在2023年学习React并不是一件容易的事情。自2019年ReactHooks发布以来,我们已经拥有了很多稳定性,但现在形势正在再次变化。而这次变化可能比使用ReactHooks时更加不稳定。在本文中,我想比较两种学习React的方式:以库的方式和以框架的方式。为了让事情更加清晰:React发布了新的文档,......
  • element使用组件el-form自动定位到未填写的必填条目
    问题:在form表单el-form中经常会出现表单条目比较多的问题,而且在提交的时候需要校验表单并且定位到相应的条目位置。解决:html:<el-formref="form":model="form":rules="rules"label-width="140px"><el-form-itemlabel="规则名称"prop="ruleName&qu......
  • 如何设计角色属性组件
    目标&背景本篇文章是对ET1中NumericComponent的介绍和补充,会围绕实际开发过程中可能会碰到的一些问题,给一个解题思路,并且会结合Luban2给出一个策划和程序都开心的方案猫大曾经对NumericComponent做出过如下评论单NumericComponent就可以完成80%Moba类游戏的设......
  • .NET 8新预览版本使用 Blazor 组件进行服务器端呈现
    简介此预览版添加了对使用Blazor组件进行服务器端呈现的初始支持。这是Blazor统一工作的开始,旨在使Blazor组件能够满足客户端和服务器端的所有WebUI需求。这是该功能的早期预览版,因此仍然受到一定限制,但我们的目标是无论选择如何构建应用,都能使用可重用的Blazor组件。......
  • vue之组件
    目录简介全局组件语法示例局部组件语法示例组件间通信父子页面通信之父传子语法示例组件通信之子传父语法示例使用ref进行父子组件通信方法示例动态组件(component)普通方法实现使用组件component实现动态组件相关keep-alive组件之插槽(slot)匿名插槽具名插槽简介组件(component......
  • 2023-04-11 使用react-draft-wysiwyg插件进行图片插入后编写文字时抛出错误:Unknown Dr
    前言:react+antd+react-draft-wysiwyg文本编辑业务场景,当我点击插入图片时,在该图片上一行或下一行进行文字输入会报如下错误:报错:UnknownDraftEntitykey:null.未知的DraftEntitykey:null。原因:当你插入图片时,新的图片img需要被包裹在一个块级元素内就不会报错(这看起来并不是原......
  • delphi 如何给自开发的组件设置图标?
    经过其他老师指点,自己摸索,发现如何实现,现说明如下,供大家参考。一、建立图标文件1、建立一个24X24的256色BMP格式文件。2、文件命名为该组件的名称。二、建立资源文件:Project→Resource and Images,点击Add将BMP格式图标文件加入,Resource Identifiler 设为组件的名称......
  • React+Antd在使用form表单提交DatePicker日期框的时候会出现少八小时的情况
    在使用antd做form表单提交的时候,突然发现了一个很有意思的bug.就是在使用datepicker组件日期框的时候会出现提交后少一天的问题我在网上搜索了许多解决办法,也是困扰了我一天的时间,下面代码.letformData=JSON.parse(JSON.stringify(form.getFieldsValue()));......
  • Vue动态创建组件实例并挂载到body
    方式一importVuefrom'vue'/***@paramComponent组件实例的选项对象*@paramprops组件实例中的prop*/exportfunctioncreate(Component,props){constcomp=new(Vue.extend(Component))({propsData:props}).$mount()document.body.appendChild(......