React 状态管理 - Redux 入门

news2024/11/25 3:39:44

目录

扩展学习资料

Redux基础

Redux动机

Redux核心概念

Redux的三个原则

Redux运转图

React & Redux的搭配使用

Redux API

React-Redux API(关联组件)

从头创建一个工程

@package.json

 @/src/reducer/index.js

@/src/reducer/home/index.js

@/src/actions/home/index.js

@/src/actions/mutation-types.js

@/src/store/index.js

@/src/index.jsx

@/src/routes/index.js

@/src/view/index.html

@/src/app.jsx

@/src/containers/home/index.jsx

小结


扩展学习资料

名称

链接

Redux 文档

Redux 中文文档 · Redux

Redux 插件

redux middleware 详解 - 知乎

构建复杂React应用

Redux基础

Redux动机

为什么需要Redux?

  • Redux适合于大型复杂的单页面应用。

单页面应用;需要管理的状态;多且复杂;页面之间共享状态

 

Redux核心概念

state : 应用全局数据的来源,数据驱动视图的核心

action: 数据发生改变动作的描述

reducer : 结合state和action,并返回一个新的state

Redux的三个原则

三大原则

  • 单一数据源 整个应用的state被储存在一棵object tree中,并且这个object tree 只存在于唯一一个store中。
  • State 是只读的 唯一改变state的方法就是触发action,action是一个用于描述已发生事件的普通对象。
  • 使用纯函数来执行修改State 可纯函数意味着同样的输入就会有同样的输出。

Redux运转图

全局状态Store操控->视图View变更触发->Actions->Reducers接收->返回给Store不同的小state构成全局状态Store

 

React & Redux的搭配使用

Redux API

  • createStore 创建一个Reudx store 来存放应用中所有的state。
  • combineReducers 将多个不同reducer函数作为value的object,合并成一个最终的reducer函数。
  • applyMiddleware 接受自定义功能的middleware来扩展Redux。
  • compose 函数式编程中的方法,右到左来组合执行参数。

React-Redux API(关联组件)

  • connect 将React组件与Redux链接起来。
  • Provider 提供被connect链接起来的组件能够访问得到Store。

从头创建一个工程

@package.json

// yarn
// 报错,清一下缓存:yarn cache clean 
{
  "name": "redux-reselect",
  "version": "1.0.0",
  "description": "reselect",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --hot --color --progress --host localhost --config webpack.config.js --env.dev",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/luzuoquan/redux-reselect.git"
  },
  "keywords": [
    "reselect",
    "redux"
  ],
  "author": "luzuoquan",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/luzuoquan/redux-reselect/issues"
  },
  "homepage": "https://github.com/luzuoquan/redux-reselect#readme",
  "devDependencies": {
    "@babel/cli": "^7.8.4",
    "@babel/core": "^7.9.6",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/plugin-proposal-decorators": "^7.8.3",
    "@babel/plugin-proposal-export-default-from": "^7.8.3",
    "@babel/plugin-transform-runtime": "^7.9.6",
    "@babel/preset-env": "^7.9.6",
    "@babel/preset-react": "^7.9.4",
    "babel-eslint": "^10.1.0",
    "babel-loader": "^8.1.0",
    "eslint": "6.8.0",
    "eslint-config-airbnb": "^18.1.0",
    "eslint-import-resolver-webpack": "^0.12.1",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-jsx-a11y": "^6.2.3",
    "eslint-plugin-react": "^7.19.0",
    "eslint-plugin-react-hooks": "3.0.0",
    "html-webpack-plugin": "^4.3.0",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.11.0"
  },
  "dependencies": {
    "@babel/runtime": "^7.9.6",
    "core-js": "^3.6.5",
    "immer": "^7.0.1",
    "prop-types": "^15.7.2",
    //react
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    // router
    "react-router": "^5.1.2",
    "react-router-dom": "^5.1.2",
    // redux
    "react-redux": "^7.2.0",
    "redux": "^4.0.5",
    "redux-thunk": "^2.3.0",
    
    "regenerator-runtime": "^0.13.5",
    "reselect": "^4.0.0",
    "whatwg-fetch": "^3.0.0"
  }
}

 @/src/reducer/index.js

import { combineReducers } from 'redux';
import homeReducer from './home';

// console.log(reSelectReducer());
// 合并多个reducer
// 扩展性
export default combineReducers({
  homeReducer,
  //...
});

@/src/reducer/home/index.js

import * as types from '@/actions/mutation-types';
// 初始值
const initialState = {
  homeName: '云',
};
// 操作
const mutations = {
  // 获取
  [types.QUERY_GLOBAL_NAME](state) {
    return { ...state }; // 解构
  },
  // 更新
  [types.UPDATE_GLOBAL_NAME](state, action) {
    return {
      ...state,
      homeName: action.payload,
    };
  },
};
export default function (state = initialState, action) {
  // 如果当前动作不存在,返回初始值
  if (!mutations[action.type]) return state;
  // 执行对应方法
  return mutations[action.type](state, action);
}

@/src/actions/home/index.js

import * as types from '../mutation-types';
// 请求数据方法
export function queryName(params) {
  return {
    type: types.QUERY_GLOBAL_NAME,
    payload: params,
  };
}
// 改变数据方法
export function updateName(params) {
  return {
    type: types.UPDATE_GLOBAL_NAME,
    payload: params,
  };
}
// 异步请求数据
export function queryAsyncName(params) {
  return (dispatch) => {
    setTimeout(() => {
      dispatch({
        type: types.QUERY_GLOBAL_NAME,
        payload: params,
      });
    }, 2000);
  };
}
// 异步修改数据
export function asynUpdatecName(params) {
  return async (dispatch) => {
    setTimeout(() => {
      dispatch(updateName(params));
    }, 3000);
  };
}

@/src/actions/mutation-types.js

// 所有动作枚举文件
// 查询
export const QUERY_GLOBAL_NAME = 'QUERY_GLOBAL_NAME';
// 更新
export const UPDATE_GLOBAL_NAME = 'UPDATE_GLOBAL_NAME';

export const FILTER_ALL_DATA = 'FILTER_ALL_DATA';
export const FILTER_SUCCESS_STATUS = 'FILTER_SUCCESS_STATUS';
export const FILTER_FAIL_STATUS = 'FILTER_FAIL_STATUS';
export const UPDATE_FILTER_STATUS = 'UPDATE_FILTER_STATUS';
export const UPDATE_IMMUTABLE_DATA = 'UPDATE_IMMUTABLE_DATA';
export const UPDATE_REDUX_ACTIONS_DATA = 'UPDATE_REDUX_ACTIONS_DATA';

@/src/store/index.js

import { createStore } from 'redux';

import reducers from '@/reducer';

export default createStore(
  reducers
);

@/src/index.jsx

import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './app';
render(
    // Provider提供被connect链接起来的组件能够访问得到Store。
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector('#app'),
);

@/src/routes/index.js

import React from 'react';
import {
  BrowserRouter,
  Route,
} from 'react-router-dom';
import Home from '@/containers/home';

export default function () {
  return (
    <BrowserRouter>
      <Route exact path="/" component={Home} />
    </BrowserRouter>
  );
}

@/src/view/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React Redux Demo</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>

@/src/app.jsx

import React from 'react';
import Routes from '@/routes';
export default () => <Routes />;

@/src/containers/home/index.jsx

/* eslint-disable react/no-unused-prop-types */
import React, { Component } from 'react';

import {
  updateName,
  queryAsyncName
} from '@/actions/home';
import { connect } from 'react-redux';
// react-redux API connect将组件与react链接起来
// connect与home页面关联起来,装饰器写法
@connect(
  (state) => state.homeReducer,
  (dispatch) => ({
    updateName: (params) => dispatch(updateName(params)),
  }),
)
export default class Home extends Component {
  handleClick = () => {
    const {
      updateName,
    } = this.props;
    updateName('修改云课堂');
  }
  render() {
    const { homeName } = this.props;
    return (
      <div>
        <div>
          {homeName}
        </div>
        <button
          type="button"
          onClick={this.handleClick}
        >
          更改
        </button>
      </div>
    );
  }
}

小结

Redux基础:核心原则【改变数据的方式只能事action】

React-Redux :只做一个单页面应用的流程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/978018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot配置统一返回结果类

目录结构&#xff1a; Result类&#xff1a; package com.xxxx.common.result;import lombok.Data;Data public class Result<T> {//状态码private Integer code;//信息private String message;//数据private T data;//构造私有化private Result() { }//设置数据,返回对…

如何分库分表?

分析&回答 分库&#xff1f;分表&#xff1f;还是既分库又分表&#xff1f; 如果需要分表&#xff0c;那么分多少张表合适&#xff1f; 由于所有的技术都是为业务服务的&#xff0c;那么&#xff0c;我们就先从数据方面回顾下业务背景。 如果每天产生 8w 笔交易单&#…

RouterOS-配置PPPoEv4v6 Server

1 接口 ether3 出接口 ether4 内网接口 2 出接口 出接口采用PPPoE拨号SLAAC获取前缀&#xff0c;手动配置后缀 2.1 选择出接口interface&#xff0c;配置PPPoE client模式 2.2 配置PPPoE client用户名和密码 2.3 从PPPoE client获取前缀地址池 2.4 给出接口选择前缀并配置…

GIS:DataStore数据管理框架

1.架构设计 OGC 规范对空间矢量数据的框架进行了设计&#xff0c;GeoTools 对其进行了实现。其中的 DataStore 可以近似理解成关系数据库中的个数据库实例&#xff0c;FeatureSource 可以近似理解成关系数据库中的一张表。 DataAccess 接口主要对空间要素类型的相关信息的构建…

MySQL连接错误1045:完美解决指南

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

第五章 数据分析模型 题目学习(40%)

第一节 主成分的计算步骤&#xff1a;1、主成分建模&#xff0c;标准化处理。2、计算特征根、特征向量。3、选取主成分个数。 题目 选择B&#xff0c;依次递减。 相关系数和关联矩阵都做了标准化&#xff0c;做完标准化后方差就不会造成影响&#xff0c;所以选A。 A可以进行判断…

JavaScript-----对象(创建对象、数组与字符串)

目录 前言&#xff1a; 1. JavaScript创建对象 1.1 对象的创建 1.2 对象的调用 1.3 for-in循环语句 2.内置对象 2.1 Array&#xff08;数组&#xff09;对象 属性和方法 2.2 String&#xff08;字符串&#xff09;对象 属性和方法 2.3 Math对象 2.4 日期对象 前言&a…

华为云API对话机器人CBS的魅力—实现简单的对话操作

云服务、API、SDK&#xff0c;调试&#xff0c;查看&#xff0c;我都行 阅读短文您可以学习到&#xff1a;人工智能AI智能的问答管理、全面的对话管理、高效训练部署 1.IntelliJ IDEA 之API插件介绍 API插件支持 VS Code IDE、IntelliJ IDEA等平台、以及华为云自研 CodeArts …

Unity项目包体优化经验方法论(Android平台)

前言 本篇文章主要讲解对于Unity Android平台也就是APK包体的优化经验&#xff0c;使用哪些工具能够更加便利的定位资源重灾区。本篇讲解的方法中对于Unity资源使用的AssetBundle的方式&#xff0c;如果使用addressable或其他资源管理方式&#xff0c;我还不是很清楚是否适用&…

Vue + Element UI 前端篇(六):更换皮肤主题

自定义主题 命令行主题工具 1.安装主题工具 首先安装「主题生成工具」&#xff0c;可以全局安装或者安装在当前项目下&#xff0c;推荐安装在项目里&#xff0c;方便别人 clone 项目时能直接安装依赖并启动。 yarn add element-theme --dev 2.安装chalk主题 安装白垩主题…

STC15单片机特有的PWM寄存器和普通定时器实现PWM输出

STC15单片机特有的PWM寄存器和普通定时器实现PWM输出 🌿主要针对STC15W4型号特有的6通道15位专门的高精度PWM。 ✨STC15W4K32S4系列单片机具有6通道15位专门的高精度PWM(带死区控制)和2通道CCP(利用它的高速脉冲输出功能可实现11~16位PWM);(STC15F/L2K60S2系列单片机具有3通…

RC-u4 相对论大师(bfs求解指定路径)

PTA | 程序设计类实验辅助教学平台 题解&#xff1a; bfs可以求解从根节点到叶子节点的指定路径&#xff0c;这里的vis[]不是为了防止访问到父节点&#xff0c;更多的是为了缩小路径长度&#xff0c;mpp和mp的映射也很巧妙&#xff0c;开始我用的还是map<pair<string,s…

用通俗易懂的方式讲解大模型分布式训练并行技术:流水线并行

近年来&#xff0c;随着Transformer、MOE 架构的提出&#xff0c;使得深度学习模型轻松突破上万亿规模参数&#xff0c;传统的单机单卡模式已经无法满足超大模型进行训练的要求。因此&#xff0c;我们需要基于单机多卡、甚至是多机多卡进行分布式大模型的训练。 而利用AI集群&…

怎么用conda下载清华源的pytorch(自带cuda的版本)

1&#xff0c;添加镜像源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…

大数据课程K22——Spark的SparkSQL的API调用

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 掌握Spark的通过api使用SparkSQL&#xff1b; 一、通过api使用SparkSQL 1. 实现步骤 1. 打开scala IDE开发环境&#xff0c;创建一个scala工程。 2. 导入spark相关依赖…

介绍 dubbo-go 并在Mac上安装,完成一次自己定义的接口RPC调用

目录 RPC 远程调用的说明作用&#xff1a;像调用本地方法一样调用远程方法和直接HTTP调用的区别&#xff1a;调用模型图示&#xff1a; Dubbo 框架说明Dubbo Go 介绍应用 Dubbo Go环境安装&#xff08;Mac 系统&#xff09;安装 Go语言环境安装 序列化工具protoc安装 dubbogo-c…

【VSCode】文件模板创建及使用.md

背景 最近使用VSCode学习Vue项目比较频繁&#xff0c;每次创建Vue文件都要手动写重复代码&#xff0c;特别麻烦&#xff0c;就上网查找自动生成代码的说明&#xff0c;结果发现VSCode有代码模板&#xff0c;怪怪&#xff0c;感觉发现新大陆了(low!)。 配置 打开配置 方式一&a…

通过slam同步建图程序看ros2节点参数传递生效顺序

缘起&#xff1a; ros2 节点参数可以通过启动节点添加&#xff0c;也可以通过launch文件添加&#xff0c;还可以通过配置文件.yaml文件添加&#xff0c;或者是几种方式套用添加&#xff0c;给初学者带来很大的困惑具体是哪个生效了呢&#xff0c;我们拿slam_toolbox 包的onli…

shell脚本介绍

当你进入Linux世界的大门时&#xff0c;就会遇到一个强大而又神奇的工具——Shell。Shell是一种命令行解释器&#xff0c;为你在Linux系统中与计算机进行互动提供了无限的可能性。 学习Shell可以让你获得强大的自动化和脚本编程能力&#xff0c;让你更高效地处理文件和目录、管…

【力扣周赛】第 357 场周赛(⭐反悔贪心)

文章目录 竞赛链接Q1&#xff1a;6925. 故障键盘解法1——直接模拟解法2——双端队列 Q2&#xff1a;6953. 判断是否能拆分数组&#xff08;贪心&#xff09;Q3&#xff1a;2812. 找出最安全路径⭐解法1——多源BFS瓶颈路模型&#xff1f;解法2——多源BFS 倒序枚举答案 并查…