当前位置: 首页 > news >正文

React学习(四) --- Redux

文章目录

  • 1. Redux前置知识
    • 1.1 纯函数回顾
    • 1.2 Redux的三个核心概念
  • 2. Redux使用
    • 2.1 规范化Redux结构
    • 2.2 Redux的三大规则
    • 2.3 react-redux --- 高阶组件封装库
    • 2.4 异步获取数据
    • 2.5 react代码调试工具
    • 2.6 Redux模块拆分
  • 3. RTK工具包
    • 3.1 redux toolkit
    • 3.2 使用RTK
      • 3.2.1 创建reducer片段 ---createSlice

1. Redux前置知识

1.1 纯函数回顾

  • 确定输入,一定会产生确定的输出;
  • 函数在执行过程中,不能产生副作用;

在这里插入图片描述
在这里插入图片描述

判断下面三个函数是否是纯函数 在这里插入图片描述

答案:

  1. 不是 (依赖外界)
  2. 不是 (改变外界)

1.2 Redux的三个核心概念

  1. store
    在这里插入图片描述

  2. action
    在这里插入图片描述

  3. reducer❗️
    在这里插入图片描述

reducer是一个纯函数,主要人物是将stateaction结合起来生成一个新的state返回,这个返回值将替换之前的state

修改state流程:

  • state.dispatch({type: ... , action: {...})
  • 触发reducer,产生新state
  • state更新

如何知道store数据修改了呢?
答:使用subscribe

componentDidMount() {// 订阅store数据this.unsubscribe = store.subscribe(() => {console.log('store change:', store.getState());})}componentWillUnmount() {// 取消订阅this.unsubscribe()}

2. Redux使用

2.1 规范化Redux结构

index.js

  • 创建store
  • 传入reducer
import { createStore } from 'redux';// const { createStore } = require('redux');  // createRedux现已弃用const initialStore = {name: "Anonymous",
}const store = createStore(reducer)export default store;

actionsCreators.js

  • 创建actions
// actions创建
export const changeNameAction = (name) => ({ type: 'change_name', name })

reducer.js

  • 单独保存reducer
import { ADD_NUMBER, CHANGE_NAME } from "./constants";// reducer 是一个纯函数
// 接收两个参数 state: 之前的状态   action: 描述要产生的改变
export function reducer(state = initialStore, action) {switch (action.type) {case CHANGE_NAME:return { ...state, name: action.name };case ADD_NUMBER:return { name }default:return state;}
}

contants.js

  • 保存type常量
// 常量
export const ADD_NUMBER = 'add_number'
export const CHANGE_NAME = 'change_name'

2.2 Redux的三大规则

在这里插入图片描述

  • 单一数据源
    • 整个应用程序的state被存储在一颗object tree中,并且这个object tree只存储在一个store中:
    • Redux并没有强制让我们不能创建多个Store,但是那样做并不利于数据的维护;
    • 单一的数据源可以让整个应用程序的state变得方便维护、追踪、修改;
  • State是只读的
    • 唯一修改State的方法一定是触发action,不要试图在其他地方通过任何的方式来修改State;
    • 这样就确保了View或网络请求都不能直接修改state,它们只能通过action来描述自己想要如何修改state;
    • 这样可以保证所有的修改都被集中化处理,并且按照严格的顺序来执行,所以不需要担心race condition(竟态)的问题;
  • 使用纯函数来执行修改
    • 通过reducer将旧state和actionsl联系在一起,并且返回一个新的State:
    • 随着应用程序的复杂度增加,我们可以将reducer拆分成多个小的reducers,分别操作不同state tree的一部分;
    • 但是所有的reducer都应该是纯函数,不能产生任何的副作用;

在这里插入图片描述
在这里插入图片描述

2.3 react-redux — 高阶组件封装库

之前讲到了高阶组件,在实际开发中我们一般使用封装好的库直接调用,而不是自己封装高阶组件,现在来学习一下react-redux这个高阶组件库,这个库主要是将reactredux联系在一起。

在这里插入图片描述

2.4 异步获取数据

在这里插入图片描述
从服务器获取数据我们可以选择在组件的componnetDidMount中发送请求获取,但其实获取数据也是需要在redux中去完成的。

所以我们选择在传递action时先获取数据再传递到reducer,但如果我们是这样写的:

 axios.get("http://123.207.32.32:8000/home/multidata").then(res => {console.log(res.data);return { type: CHANGE_BANNERS, banners: [] }}).catch(err => {return { type: CHANGE_BANNERS, banners: [] }})

也就是获取数据后直接返回一个action对象,但其实返回的会是一个Promise对象,不符合redux的规范(传入一个action对象或者一个中间件函数)。

中间件我们需要使用到redux-thunk这个库,首先进行安装:

npm i redux-thunk

const store = createStore(reducer, applyMiddleware(thunk));

之后就可以创建异步获取数据的action

// 异步获取数据的action
export const fetchHomeDataAction = () => {// 使用redux-thunk中间件,返回一个函数(内置dispatch和getState)return (dispatch, getState) => {axios.get("http://123.207.32.32:8000/home/multidata").then(res => {console.log(res.data, res.data.data.banner.list);dispatch(changeBannersAction(res.data.data.banner.list))})}
}

需要注意的是返回的函数中thunk内置了dispatchgetState,这里只需要调用普通的action修改数据即可。

2.5 react代码调试工具

首先安装这两个工具

  • redux-devtools
  • react-devtools

默认开发环境开启,生产环境关闭。

在这里插入图片描述

2.6 Redux模块拆分

在这里插入图片描述

3. RTK工具包

3.1 redux toolkit

  • 在前面我们学习Redux的时候应该已经发现,redux的编写逻辑过于的繁琐和麻烦。
  • 并且代码通常分拆在多个文件中(虽然也可以放到一个文件管理,但是代码量过多,不利于管理);
  • ReduxToolkit包旨在成为编写Redux逻辑的标准方式,从而解决上面提到的问题;
  • 在很多地方为了称呼方便,也将之称为"RTK”;

npm i @reduxjs/tookit react-redux

在这里插入图片描述

3.2 使用RTK

3.2.1 创建reducer片段 —createSlice

  • name: 代替action的type;
  • initialState: 初始值;
  • reducers: 与之前的一样,但这里需要注意是函数
import { createSlice } from "@reduxjs/toolkit";const counterSlice = createSlice({name: 'counter',initialState: {counter: 888},reducers: {addNumber(state, action) {state.counter++}}
})// 导出的是counterSlice.reducer  (不是counterSlice.reducers)
export default counterSlice.reducer

index.js

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from './modules/counter';const store = configureStore({reducer: {counter: counterReducer}
})export default store;
http://www.dtcms.com/a/483250.html

相关文章:

  • Codeforces Round 1058 (Div. 2)(A-D)
  • SQL Server 2019实验 │ 高级查询
  • 建站宝盒建站系统网站管理建设需进一步加强
  • 网站开发步骤网站备案身份核验
  • Linux中paging_init页表初始化函数的实现
  • 端侧大模型推理笔记
  • 可以建立网站的平台seo专业课程
  • 网站在那里备案企业信息管理系统的设计与实现
  • 设备管理系统原型设计实战:PC/APP/PDA多端页面解析
  • 西安建设教育网站wordpress homepage
  • Transformer-输入部分
  • Python接口与抽象基类详解:从规范定义到高级应用
  • 免费网站建设价格费用.net做网站用什么的多
  • 专业高端网站建设服务公司百度指数趋势
  • AI商品换模特及场景智能化
  • 网站开发定制推广杭州视频在线生成链接
  • 异步任务使用场景与实践
  • 300多个Html5小游戏列表和下载地址
  • 企业门户网站方案建网站有报价单吗
  • 企业网站开发价钱低免费开个人网店
  • 建网站软件下载那个软件可以做三个视频网站
  • Excel使用教程笔记
  • 论文阅读《LIMA:Less Is More for Alignment》
  • wordpress 网站暂停app建设网站
  • 考研408--组成原理--day1
  • 网络公司构建网站杭州旅游团购网站建设
  • 【数值分析】非线性方程与方程组的数值解法的经典算法(附MATLAB代码)
  • 文件外链网站智慧团建官网登录入口电脑版
  • 如何在Windows上为Java配置多个版本的环境变量
  • 如何将自己做的网站放到网上去如何做电商创业