React 状态管理 - Redux 进阶(下)提升开发体验

news/2024/10/18 5:51:07/

目录

扩展学习资料

Reselect【数据持久化】&Immutable Data【不变数据】方案【解决某些场景重复渲染,重复计算的问题】

@/src/reducer/index.js

Reselect【 可缓存的筛选项,当数据量大的时候,可以节省diff时间,提升渲染效率】

@src/reducer/reselect/index.js

@/src/actions/reselect/index.js

@/src/containers\reselect\index.jsx

 @/src/store/index.js

Immutable Data

Immutable方案

@/src/containers/immutable/index.jsx

 @/src/actions/immutable/index.js

@/src/reducer/immutable/index.js

redux-actions & @rematch/core & dva【比较高阶状态管理方案】

@/src/actions/redux-actions/index.js

@/src/containers/redux-actions/index.jsx

@/src/reducer/redux-actions/index.js

Reudx的不足

redux-actions & @rematch/core & dva


扩展学习资料

名称

链接

备注

redux-actions

Introduction - redux-actions

英文

@rematch/core

Rematch | Rematch

dva

介绍 | DvaJS

Reselect【数据持久化】&Immutable Data【不变数据】方案【解决某些场景重复渲染,重复计算的问题】

@/src/reducer/index.js

import { combineReducers } from 'redux';
import homeReducer from './home';
import reSelectReducer from './reselect';
import immutableReducer from './immutable';
import reduxActionsReducer from './redux-actions';
// console.log(reSelectReducer());
// 合并多个reducer
// 扩展性
export default combineReducers({homeReducer,reSelectReducer,immutableReducer,reduxActionsReducer,
});

Reselect【 可缓存的筛选项,当数据量大的时候,可以节省diff时间,提升渲染效率】

  • 针对mapStateToProps中state在同一数据源中需要筛选的场景
  • mapStateToProps中state如果带有筛选函数,会导致每次返回新对象

@src/reducer/reselect/index.js

import * as types from '@/actions/mutation-types';
const initialState = {reSelectList: [{key: '001',status: true,name: 'flex-reselect-1',}, {key: '002',status: true,name: 'flex-reselect-2',}, {key: '003',status: false,name: 'flex-reselect-3',}, {key: '004',status: true,name: 'flex-reselect-4',}, {key: '005',status: false,name: 'flex-reselect-5',}, {key: '006',status: false,name: 'flex-reselect-6',}, {key: '007',status: true,name: 'flex-reselect-7',}],filterStatus: 'FILTER_ALL_DATA',
};
const mutations = {[types.FILTER_ALL_DATA](state) {return { ...state };},[types.UPDATE_FILTER_STATUS](state, action) {return {...state,filterStatus: action.payload,};},
};
export default function (state = initialState, action) {if (!mutations[action.type]) return state;return mutations[action.type](state, action);
}

@/src/actions/reselect/index.js

import * as types from '../mutation-types';
export function filterData(data, filter) {console.log(filter, 'filter', Date.now());switch (filter) {case types.FILTER_ALL_DATA:return data;case types.FILTER_SUCCESS_STATUS:return data.filter(item => item.status);case types.FILTER_FAIL_STATUS:return data.filter(item => !item.status);default:return data;}
}
export function updateFilterStatus(params) {return {type: types.UPDATE_FILTER_STATUS,payload: params,};
}

@/src/containers\reselect\index.jsx

import React, { Component } from 'react';
import propTypes from 'prop-types';
import { connect } from 'react-redux';
// 可缓存的筛选项,当数据量大的时候,可以节省diff时间,提升渲染效率
import { createSelector } from 'reselect';
import {filterData,updateFilterStatus,
} from '@/actions/reselect';
const filterStatusMap = {1: 'FILTER_ALL_DATA',2: 'FILTER_SUCCESS_STATUS',3: 'FILTER_FAIL_STATUS',
};
const getReselectList = (state) => state.reSelectReducer.reSelectList;
const getFilterStatus = (state) => state.reSelectReducer.filterStatus;
// 一个可以缓存的数据源,避免了数据的重复计算,和页面更新
const filterReselectData = createSelector([getReselectList, getFilterStatus],(list, filter) => filterData(list, filter),
);
// filterData(
//   state.reSelectReducer.reSelectList,
//   state.reSelectReducer.filterStatus,
// )
@connect((state) => ({filterList: filterReselectData(state),}),(dispatch) => ({updateFilterStatus: (params) => dispatch(updateFilterStatus(params)),}),
)
export default class ReselectDemo extends Component {handleUpdate = (signal) => {const { updateFilterStatus } = this.props;updateFilterStatus(filterStatusMap[signal]);// console.log(signal, this.props, updateFilterStatus);}render() {const { filterList } = this.props;return (<div><>{filterList.map(item => (<div key={item.key}><span>{item.name}</span>&nbsp;&nbsp;<span>{String(item.status)}</span></div>))}</><button type="button" onClick={() => this.handleUpdate(1)}>全部</button><button type="button" onClick={() => this.handleUpdate(2)}>成功</button><button type="button" onClick={() => this.handleUpdate(3)}>失败</button></div>);}
}
ReselectDemo.propTypes = {filterList: propTypes.arrayOf(propTypes.object),updateFilterStatus: propTypes.func,
};
ReselectDemo.defaultProps = {filterList: [],updateFilterStatus: () => null,
};

 @/src/store/index.js

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducers from '@/reducer';
const middlewares = [thunk];
// 配合浏览器安装的redux开发者工具
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export default createStore(reducers,composeEnhancers(applyMiddleware(...middlewares)),
);

Immutable Data

  • 避免副作用
  • 状态可追溯
  • React中比较是shallowCompare【浅比较,判断是否重绘】

Immutable方案

immutable.js

  • 提供完整的API,与普通的JS对象不同,两者不能直接使用
  • 对Redux的应用程序来说,整个state tree应该是Immutable.JS对象,根本不需要使用普通的JavaScript对象

immer.js【让状态可追溯、避免副作用、纯函数,大型项目必备,避免一些不必要的问题:健壮性,维护问题】

  • JS原生数据结构实现的immutable也提供了一套应对的API,相比immutable更推荐使用

@/src/containers/immutable/index.jsx

import React, { Component } from 'react';
import { connect } from 'react-redux';
import propTypes from 'prop-types';
import updateImmutableData from '@/actions/immutable';
@connect((state) => {console.log(state.immutableReducer);return ({complexData: state.immutableReducer.complexData,});},(dispatch) => ({updateImmutableData: (params) => dispatch(updateImmutableData(params)),}),
)
export default class ImmutableDemo extends Component {handleClick = () => {const { updateImmutableData } = this.props;updateImmutableData('immutable 云');}render() {const { complexData } = this.props;return (<div><div>{complexData?.commonInfo?.name?.firstName}</div><button type="button" onClick={this.handleClick}>更改</button></div>);}
}
ImmutableDemo.propTypes = {complexData: propTypes.objectOf(propTypes.object),updateImmutableData: propTypes.func,
};
ImmutableDemo.defaultProps = {complexData: {},updateImmutableData: () => null,
};

 @/src/actions/immutable/index.js

import * as types from '../mutation-types';
export default function updateImmutableData(params) {return {type: types.UPDATE_IMMUTABLE_DATA,payload: params,};
}

@/src/reducer/immutable/index.js

import produce from 'immer';
import * as types from '@/actions/mutation-types';
const initialState = {complexData: {commonInfo: {name: {firstName: '云',secondName: 'Fedora',},},specialInfo: {address: '网商路24599号',},},
};
const mutations = {[types.UPDATE_IMMUTABLE_DATA](state, action) {return produce(state, draftState => {// eslint-disable-next-line no-param-reassigndraftState.complexData.commonInfo.name.firstName = action.payload;console.log('oldState', state);});// const { complexData } = state;// const newComplexData = { ...complexData };// newComplexData.commonInfo.name.firstName = action.payload;// 改变了源,产生了副作用,无法回溯// console.log('newComplexData Vs complexData', newComplexData, complexData);// return {//   ...state,//   complexData: newComplexData,// };},
};
export default function (state = initialState, action) {if (!mutations[action.type]) return state;return mutations[action.type](state, action);
}

redux-actions & @rematch/core & dva【比较高阶状态管理方案】

Redux扩展&更多状态管理方案

@/src/actions/redux-actions/index.js

import * as types from '../mutation-types';
export default function updateReduxActions(params) {return {type: types.UPDATE_REDUX_ACTIONS_DATA,payload: params,};
}

@/src/containers/redux-actions/index.jsx

import React, { Component } from 'react';
import { connect } from 'react-redux';
import propTypes from 'prop-types';
@connect((state) => state.reduxActionsReducer)
export default class ReduxActionsDemo extends Component {render() {const { actionName } = this.props;return (<div>{actionName}</div>);}
}
ReduxActionsDemo.propTypes = {actionName: propTypes.string,
};
ReduxActionsDemo.defaultProps = {actionName: '',
};

@/src/reducer/redux-actions/index.js

import * as types from '@/actions/mutation-types';
const initialState = {actionName: '云',
};
const mutations = {[types.UPDATE_REDUX_ACTIONS_DATA](state, action) {return {...state,actionName: action.payload,};},
};
export default function (state = initialState, action) {if (!mutations[action.type]) return state;return mutations[action.type](state, action);
}

Reudx的不足

  • Redux范式繁琐 完成一次页面渲染,需要在Action层分别定义type,Action方法,Reducer中响应Action方法。完成一次流程需要在多个文件夹中来回切换
  • 基础功能匮乏 默认只有同步方法,异步数据请求需要安装插件(redux-thunk),复杂功能交由第三方插件完成,有一定的接入成本。

redux-actions & @rematch/core & dva

  • 三种解决方案的对比:都解决了多层范式【写一个redux要改好多文件夹里的文件】

旧的react项目redux解决多层范式问题建议使用redux-actions;e

新的react项目建议使用dva或@rematch/core是比较成熟的框架;有中文文档

选择技术方案的着重点:

1.接入成本:学习的曲线

2.改造成本:使用后,团队的是否接受,收益是什么,纯技术类还是包含产品类

3.团队方案:社区是否完善【市场层面,学习圈层面是否足够大】,技术栈是否贴合【与我们团队的技术栈是否贴合】


http://www.ppmy.cn/news/1095830.html

相关文章

2023京东医疗保健器械行业数据分析(京东数据分析平台)

随着人们对自身健康的重视程度不断加深&#xff0c;当前市场中各类对疾病具有诊断、预防、监护、治疗或者缓解的医疗保健仪器越来越受到消费者的关注。 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;今年7月份&#xff0c;京东平台医疗保健仪器的销量为950万&#xf…

*** error 65: access violation at 0xFFFFFFF4 : no ‘write‘ permission怎么办

我发现是我的单片机型号设置错了&#xff0c;把debug里面的STM32F103ZET6修改为STM32F103ZE就可以正常运行了

laravel框架系列(一),Dcat Admin 安装

介绍 Laravel 是一个流行的 PHP 开发框架&#xff0c;它提供了一套简洁、优雅的语法和丰富的功能&#xff0c;用于快速构建高质量的 Web 应用程序。 以下是 Laravel 的一些主要特点和功能&#xff1a; MVC 架构&#xff1a;Laravel 使用经典的模型-视图-控制器&#xff08;MV…

算法通关村第十六关:黄金挑战:滑动窗口与堆结合

黄金挑战&#xff1a;滑动窗口与堆结合 堆的大小一般是有限的&#xff0c;能直接返回当前位置下的最大值或者最小值 该特征与滑动窗口结合&#xff0c;可以解决一些特定场景的问题 1. 滑动窗口与堆问题的结合 LeetCode239 https://leetcode.cn/problems/sliding-window-maxi…

API的测试1688平台的封装API接口

API的测试1688平台免费测试 API测试是一种软件测试&#xff0c;涉及直接测试API&#xff0c;并且是集成测试的一部分&#xff0c;以检查API是否在应用程序的功能&#xff0c;可靠性&#xff0c;性能和安全性方面达到期望。在API测试中&#xff0c;我们的主要重点是软件体系结构…

C#扩展方法

参数列表中this的这种用法是在.NET 3.0之后新增的一种特性---扩展方法。通过这个属性可以让程序员在现有的类型上添加扩展方法&#xff08;无需创建新的派生类型、重新编译或者以其他方式修改原始类型&#xff09;。 扩展方法是一种特殊的静态方法&#xff0c;虽然是静态方法&a…

说说MySQL回表查询与覆盖索引

分析&回答 什么是回表查询&#xff1f; 通俗的讲就是&#xff0c;如果索引的列在 select 所需获得的列中&#xff08;因为在 mysql 中索引是根据索引列的值进行排序的&#xff0c;所以索引节点中存在该列中的部分值&#xff09;或者根据一次索引查询就能获得记录就不需要…

MYSQL学习之——管理用户

MYSQL学习之——管理用户&#xff08;DCL&#xff09; 用户这个东西其实是一个和TABLE DATABASE 这种东西一样的并列关键字。 用户的管理无外乎几个操作 查看用户 添加用户 删除用户 更新用户名或密码 改变用户对数据库的操作权限。 MYSQL语句功能备注USE mysql; select * FR…