React - redux 使用(由浅入深)
创始人
2024-03-23 10:19:43
0

React - redux 使用(由浅入深)

  • 一. redux理解
    • 1. redux 介绍
    • 2. redux 使用情况
    • 3. redux 工作流程
    • 4. redux 三个核心概念
      • 4.1 Action
      • 4.2 Store
      • 4.3 Reducers
    • 5. redux 核心API
      • 5.1 createStore()
      • 5.2 Store
        • 5.2.1 Store 方法
          • 5.2.1.1 getState()
          • 5.2.1.2 dispatch(action)
          • 5.2.1.3 subscribe(listener)
  • 二. redux精简版使用(不使用 Action)
  • 三. redux完整版使用(在 redux精简版基础上使用 Action)
  • 四. redux 异步action(在 redux完整版基础上使用 异步action)
  • 五. react-redux 的基本使用(在 redux 异步action修改使用 react-redux)
  • 六. react-redux 的优化使用(在 react-redux 的基本使用 中修改)
  • 七. react-redux 数据共享(在 react-redux 的优化使用 中修改)
  • 八. react-redux 总体优化(在 react-redux 数据共享 中修改)
  • 九. react-redux 开发者工具的使用
  • 十. react-redux 正规使用流程
    • 1. 准备工作,创建 redux 所需文件
    • 2. 安装 redux 所需的依赖,编写基础代码
    • 3. 编写组件功能
      • 3.1 Count 组件 实例
      • 3.2 Persons 组件 实例
      • 3.3 Count组件 和 Persons 组件 相互通信
      • 3.4 页面展示

中文文档:http://www.redux.org.cn/
英文文档:https://redux.js.org/
Github:https://github.com/reactjs/redux
可直接参照 目录十 进行使用 react-redux

一. redux理解

1. redux 介绍

  • redux 是一个专门用于做状态管理的JS库(不是react插件库)。
  • 它可以用在 react, angular, vue 等项目中, 但基本与 react 配合使用。
  • 作用: 集中式管理 react 应用中多个组件共享的状态。
  • 可以构建一致化的应用,运行于不同的环境(客户端、服务器、原生应用),并且易于测试。
  • 体小精悍(只有2kB,包括依赖),却有很强大的插件扩展生态。

2. redux 使用情况

  • 一个状态多个组件使用,多个组件可以随时拿到(共享)。
  • 一个组件需要改变另一个组件的状态(通信)。
  • 能不使用就不使用, 状态共享使用不方便时考虑使用。

3. redux 工作流程

在这里插入图片描述

4. redux 三个核心概念

4.1 Action

  • 可以省略创建。
  • 把数据从应用传到 store 的有效载荷,Action 是 store 数据的唯一来源。
  • 一般来说会通过 store.dispatch() 将 action 传到 store。
  • 有两个属性
    type :标识属性, 值为字符串, 唯一, 必要属性。
    data :数据属性, 值类型任意, 可选属性

4.2 Store

  • 用来维持应用所有的 state 树 的一个对象,改变 store 内 state 的惟一途径是对它 dispatch 一个 action。
  • Store 不是类,它只是有几个方法的对象。 要创建它,只需要把根部的 reducing 函数传递给 createStore。

4.3 Reducers

  • 指定了应用状态的变化如何响应 actions 并发送到 store 。
  • Reduce r函数会接收到两个参数,分别为:之前的状态动作对象
  • Reducer 有两个作用:初始化状态、加工状态。
  • Reducer 的第一次调用时,是store自动触发的,传递的 preState(之前的状态) 是undefined

5. redux 核心API

5.1 createStore()

  • 创建一个 Redux store 来以存放应用中所有的 state。
  • 应用中应有且仅有一个 store。

5.2 Store

  • 用来维持应用所有的 state 树 的一个对象。 改变 store 内 state 的惟一途径是对它 dispatch 一个 action。
  • Store 不是类。它只是有几个方法的对象。 要创建它,只需要把根部的 reducing 函数传递给 createStore。

5.2.1 Store 方法

5.2.1.1 getState()

store.getState()

  • 返回应用当前的 state 树。
  • 它与 store 的最后一个 reducer 返回值相同。
5.2.1.2 dispatch(action)

store.dispatch(action)

  • 分发 action。这是触发 state 变化的惟一途径。
  • 会使用当前 getState() 的结果和传入的 action 以同步方式的调用 store 的 reduce 函数。返回值会被作为下一个 state。
5.2.1.3 subscribe(listener)

store.subscribe(() => { });

  • 添加一个变化监听器。每当 dispatch action 的时候就会执行,state 树中的一部分可能已经变化。可以在回调函数里调用 getState() 来拿到当前 state。
  • 状态改变后重新渲染,有两种方法:
    (1)在组件的 componentDidMount 生命周期钩子中调用 store.subscribe
    componentDidMount() {// 监听redux中状态的变化,只要变化,就调用renderstore.subscribe(() => {//状态假更新,每次状态更新都会调用renderthis.setState({});});
    }
    
    (2)在 index.js 文件中检测 store 中状态的改变,一旦发生改变重新渲染
    import React from "react";
    import reactDOM from "react-dom";
    import App from "./App";
    import store from "./redux/store";
    reactDOM.render(, document.getElementById("root"));
    // store中状态改变,重新渲染dom
    store.subscribe(() => {reactDOM.render(, document.getElementById("root"));
    });
    

二. redux精简版使用(不使用 Action)

  1. src 文件夹下创建一个 redux 文件夹,并在 redux 文件夹中创建两个文件,分别是:store.jscount_reducer.js,对应store,reducer
  2. store.js中修改

    1.引入redux中的createState函数,创建一个store
    2. createState调用时,要传入一个为其服务的reducer
    3. 记得暴露 store

    /*** 该文件专门用于暴露一个store对象,整个应用只有一个store对象*/
    // 引入createStore,专门用于创建redux中最为核心的store对象
    import { createStore } from "redux";
    // 引入为count组件服务的reducer
    import countReducer from "./count_reducer";const store = createStore(countReducer);
    export default store;
    
  3. count_reducer.js中修改
    /*** 1. 该文件是用于创建一个为为Count组件服务的reducer,reducer的本质是一个函数* 2. reducer函数会接收到两个参数,分别为:之前的状态(preState),动作对象(action)*/
    const intState = 0; //初始化状态
    // preState===undefined时,preState = intState
    export default function countReducer(preState = intState, action) {// 从action对象中获取:type,dataconst { type, data } = action;// 根据type决定加工数据switch (type) {// 加case "increment":return preState + data;//  减case "decrement":return preState - data;default:return preState;}
    }
    
  4. 组件中使用
    1. 获取状态:store.getState()
    2. 改变状态:store.dispatch({ type: “方法类型”, data: 需要操作的数据 })
    3. 状态改变后重新渲染
    import React, { Component } from "react";
    // 引入store,用于获取redux中保存的状态
    import store from "../../redux/store";export default class Count extends Component {/*** 在index.js中监听状态改变进行渲染,一劳永逸*/// componentDidMount() {//   // 监听redux中状态的变化,只要变化,就调用render//   store.subscribe(() => {//     // 假更新//     this.setState({});//   });// }//   加法increment = () => {const { value } = this.selectNumber;store.dispatch({ type: "increment", data: value * 1 });};//   减法decrement = () => {const { value } = this.selectNumber;store.dispatch({ type: "decrement", data: value * 1 });};//   奇数再加incrementIfOdd = () => {const { value } = this.selectNumber;const count = store.getState();if (count % 2 !== 0) {store.dispatch({ type: "increment", data: value * 1 });}};//   异步加incrementAsync = () => {const { value } = this.selectNumber;setTimeout(() => {store.dispatch({ type: "increment", data: value * 1 });}, 500);};render() {return (

    当前求和为:{store.getState()}

            
    );} }

三. redux完整版使用(在 redux精简版基础上使用 Action)

  1. 在redux文件夹中新增两个文件,分别是:constant.jscount__action.js
    constant.js 放置容易写错的type值
    count__action.js 专门用于创建action对象
  2. constant.js 文件修改
    /*** 该模块用于定义action对象中type类型的常量值* 目的只有一个:便于管理的同时防止程序员单词写错*/
    export const INCREMENT = "increment";
    export const DECREMENT = "decrement";
    
  3. count__action.js 文件修改
    /*** 该文件专门为Count组件生成action对象*/
    import { INCREMENT, DECREMENT } from "./constant";// 正常方式
    // export const createIncrementAction = (data) => {
    //   return { type: "increment", data };
    // };
    // 简写方式
    export const createIncrementAction = (data) => ({ type: INCREMENT, data });
    export const createDecrementAction = (data) => ({ type: DECREMENT, data });
    
  4. count_reducer.js文件修改,使用 constant.js 文件
    /*** 1. 该文件是用于创建一个为为Count组件服务的reducer,reducer的本质是一个函数* 2. reducer函数会接收到两个参数,分别为:之前的状态(preState),动作对象(action)*/
    import { INCREMENT, DECREMENT } from "./constant";const intState = 0; //初始化状态
    export default function countReducer(preState = intState, action) {// 从action对象中获取:type,dataconst { type, data } = action;// 根据type决定加工数据switch (type) {// 加case INCREMENT:return preState + data;//  减case DECREMENT:return preState - data;default:return preState;}
    }
    
  5. 使用的组件中修改
    import React, { Component } from "react";
    // 引入store,用于获取redux中保存的状态
    import store from "../../redux/store";
    // 引入actionCreator,专门用于创建action对象
    import {createIncrementAction,createDecrementAction,
    } from "../../redux/count_action";export default class Count extends Component {//   加法increment = () => {const { value } = this.selectNumber;store.dispatch(createIncrementAction(value * 1));};//   减法decrement = () => {const { value } = this.selectNumber;store.dispatch(createDecrementAction(value * 1));};//   奇数再加incrementIfOdd = () => {const { value } = this.selectNumber;const count = store.getState();if (count % 2 !== 0) {store.dispatch(createIncrementAction(value * 1));}};//   异步加incrementAsync = () => {const { value } = this.selectNumber;setTimeout(() => {store.dispatch(createIncrementAction(value * 1));}, 500);};render() {return (

    当前求和为:{store.getState()}

            
    );} }

四. redux 异步action(在 redux完整版基础上使用 异步action)

  1. 安装 redux-thunk
    yarn add redux-thunk
  2. store.js 中修改配置redux-thunk
    /*** 该文件专门用于暴露一个store对象,整个应用只有一个store对象*/// 引入createStore,专门用于创建redux中最为核心的store对象
    import { createStore, applyMiddleware } from "redux";
    // 引入为count组件服务的reducer
    import countReducer from "./count_reducer";
    // 引入redux-thunk,用于支持异步action
    import thunk from "redux-thunk";const store = createStore(countReducer, applyMiddleware(thunk));
    export default store;
    
  3. count_action.js 文件中配置 异步action
    /*** 该文件专门为Count组件生成action对象*/
    import { INCREMENT, DECREMENT } from "./constant";
    /*** 同步action,就是指action的值为Object类型的一般对象*/
    // 正常方式
    // export const createIncrementAction = (data) => {
    //   return { type: "increment", data };
    // };
    // 简写方式
    export const createIncrementAction = (data) => ({ type: INCREMENT, data });
    export const createDecrementAction = (data) => ({ type: DECREMENT, data });
    /*** 异步action,就是指action的值是函数,异步action中一般都会调用同步action,异步action不是必须要用的*/
    export const createIncrementAsyncAction = (data, time) => {return (dispatch) => {setTimeout(() => {// 异步任务有结果后,分发一个同步的action去真正操作数据dispatch(createIncrementAction(data));}, time);};
    };
    
  4. 组件中修改使用 异步action
    // 引入actionCreator,专门用于创建action对象
    import {createIncrementAction,createDecrementAction,createIncrementAsyncAction,
    } from "../../redux/count_action";//   异步加
    incrementAsync = () => {const { value } = this.selectNumber;// setTimeout(() => {store.dispatch(createIncrementAsyncAction(value * 1, 500));// }, 500);
    };
    

五. react-redux 的基本使用(在 redux 异步action修改使用 react-redux)

  1. 安装 react-redux
    yarn add react-redux
  2. 创建一个容器组件

    1.在 src 文件夹下创建一个 containers 容器文件夹
    2.containers 文件夹中创建一个 Count 文件夹
    3.Count 文件夹下创建一个index.jsx文件

    // 引入Count的UI组件
    import CountUI from "../../components/Count";
    // 引入connect用于连接UI组件与redux
    import { connect } from "react-redux";
    // 引入action
    import {createIncrementAction,createDecrementAction,createIncrementAsyncAction,
    } from "../../redux/count_action";/*** 1. mapStateToProps 函数的返回值是一个对象* 2. 返回的对象中的key作为传递给UI组件props的key,value作为传递给UI组件的props的value* 3. mapStateToProps 函数用于传递状态*/
    function mapStateToProps(state) {return {count: state,};
    }
    /*** 1. mapDispatchToProps 函数的返回值是一个对象* 2. 返回的对象中的key作为传递给UI组件props的key,value作为传递给UI组件的props的value* 3. mapDispatchToProps 函数用于传递操作状态的方法*/
    function mapDispatchToProps(dispatch) {return {add: (data) => {// 通知redux执行方法dispatch(createIncrementAction(data));},delete: (data) => dispatch(createDecrementAction(data)),addAsync: (data, time) => dispatch(createIncrementAsyncAction(data, time)),};
    }
    // 使用connect()()创建并暴露一个Count的容器组件
    export default connect(mapStateToProps, mapDispatchToProps)(CountUI);
    
  3. App.js 文件中修改引入的容器组件地址,并传入 store
    import React, { Component } from "react";
    import Count from "./containers/Count";
    import store from "./redux/store";export default class App extends Component {render() {return (
    {/* 给容器组件传递store */}store} />
    );} }
  4. 修改组件中获取状态和修改状态的方式,通过this.props方式
    • 获取状态:
      this.props.count
    • 调用 action 修改状态,对应mapDispatchToProps中的方法
      this.props.add(value * 1);

六. react-redux 的优化使用(在 react-redux 的基本使用 中修改)

  1. 容器组件 和 UI组件 合并成一个组件
    connect模板:

    export default connect((state) => ({ key: value }),//映射状态{ key: action方法, }//映射操作状态的方法
    )(UI组件);
    

    1.将 src/component/Count/index.jsx 中的内容 剪切放入 src/container/Count/index.jsx
    2.并删除 src/component 中的Count组件
    3.优化connect()()写法,简化mapDispatchToProps写法

    import React, { Component } from "react";
    // 引入connect用于连接UI组件与redux
    import { connect } from "react-redux";
    // 引入action
    import {createIncrementAction,createDecrementAction,createIncrementAsyncAction,
    } from "../../redux/count_action";class Count extends Component {//   加法increment = () => {const { value } = this.selectNumber;this.props.add(value * 1);};//   减法decrement = () => {const { value } = this.selectNumber;this.props.delete(value * 1);};//   奇数再加incrementIfOdd = () => {const { value } = this.selectNumber;if (this.props.count % 2 !== 0) {this.props.add(value * 1);}};//   异步加incrementAsync = () => {const { value } = this.selectNumber;this.props.addAsync(value * 1,500);};render() {console.log("UI组件接收到的props值:", this.props);return (

    当前求和为:{this.props.count}

            
    );} }/*** 拆分函数写法 // 映射状态 const mapStateToProps = (state) => ({ count: state }); // 映射操作状态的方法 const mapDispatchToProps = (dispatch) => ({add: (data) => dispatch(createIncrementAction(data)),delete: (data) => dispatch(createDecrementAction(data)),addAsync: (data, time) => dispatch(createIncrementAsyncAction(data, time)), });// 使用connect()()创建并暴露一个Count的容器组件 export default connect(mapStateToProps, mapDispatchToProps)(Count); *//*** 合并函数写法*/ // 使用connect()()创建并暴露一个Count的容器组件 export default connect((state) => ({ count: state }),// mapDispatchToProps 的一般写法// (dispatch) => ({// add: (data) => dispatch(createIncrementAction(data)),// delete: (data) => dispatch(createDecrementAction(data)),// addAsync: (data, time) => dispatch(createIncrementAsyncAction(data, time)),// })// mapDispatchToProps 的简写{add: createIncrementAction,delete: createDecrementAction,addAsync: createIncrementAsyncAction,} )(Count);
  2. 修改 App.jsx,无需自己给容器组件传递store

    import React, { Component } from "react";
    import Count from "./containers/Count";export default class App extends Component {render() {return (
    );} }
  3. 修改 index.js 文件

    1.去除store.subscribe(() => { });状态监听
    2.给包裹一个标签
    Provider:让所有组件都可以得到state数据

    import React from "react";
    import reactDOM from "react-dom";
    import App from "./App";
    import store from "./redux/store";
    import { Provider } from "react-redux";
    reactDOM.render(store}>,document.getElementById("root")
    );
    

七. react-redux 数据共享(在 react-redux 的优化使用 中修改)

  1. 修改 src/redux/constant.js 文件,新增常量值
    export const INCREMENT = "increment";
    export const DECREMENT = "decrement";
    export const ADD_PERSON = "add_person";
    
  2. src/redux 文件夹中创建一个 actions 文件夹,将所有的 action文件 放入。在其中创建一个person 的 action文件,用于为 person组件reducer服务
    import { ADD_PERSON } from "../constant";// 创建增加一个人的action对象
    export const creactAddPersonAction = (personObj) => {return { type: ADD_PERSON, data: personObj };
    };
    
  3. src/redux 文件夹中创建一个 reducers 文件夹,将所有的 reducers文件 放入。在其中创建一个 person 的reducers文件
    import { ADD_PERSON } from "../constant";
    // 初始化人员列表
    const initState = [{ id: 1, name: "tom", age: 20 }];
    export default function personReducer(preState = initState, action) {console.log('person')const { type, data } = action;switch (type) {// 添加case ADD_PERSON:return [data, ...preState];default:return preState;}
    }
    
  4. 修改 store.js 文件,引入 combineReducers ,用于汇总所有的reducer,变为一个整的reducer
    /*** 该文件专门用于暴露一个store对象,整个应用只有一个store对象*/// 引入createStore,专门用于创建redux中最为核心的store对象
    import { createStore, applyMiddleware,combineReducers } from "redux";
    // 引入为count组件服务的reducer
    import countReducer from "./reducers/count";
    // 引入Person组件服务的reducer
    import personReducer from './reducers/person'
    // 引入redux-thunk,用于支持异步action
    import thunk from "redux-thunk";// 汇总所有的reducer,变为一个整的reducer
    const allReducer = combineReducers({total:countReducer,persons:personReducer
    })
    const store = createStore(allReducer, applyMiddleware(thunk));
    export default store;
    
  5. 新增一个 Person 组件,和Count组件通过 redux 共享数据

    取出 redux 状态时,要取到对象组件的key值

    import React, { Component } from "react";
    import { connect } from "react-redux";
    import { creactAddPersonAction } from "../../redux/actions/person";class Person extends Component {addPerson = () => {const name = this.nameNode.value;const age = this.ageNode.value;const id = this.props.personList.length + 1;let personObj = {id,name,age,};this.props.addPerson(personObj);this.nameNode.value = "";this.ageNode.value = "";};render() {return (

    Person 组件

    上方Count组件的总和为:{this.props.total}

    (cur) => (this.nameNode = cur)}type="text"placeholder="请输入姓名"/>(cur) => (this.ageNode = cur)}type="text"placeholder="请输入年龄"/>
      {this.props.personList.map((v) => {return (
    • v.id}>姓名:{v.name},年龄:{v.age}
    • );})}
    );} }const mapStateToProps = (state) => ({personList: state.persons,total: state.total, });const mapDispatchToProps = {addPerson: creactAddPersonAction, };export default connect(mapStateToProps, mapDispatchToProps)(Person);

八. react-redux 总体优化(在 react-redux 数据共享 中修改)

  1. 所有的变量名尽可能规范,并触发对象的简写方式
    • 汇总 reducer
    // 引入combineReducers,用于汇总所有的reducer
    import { combineReducers } from "redux";
    // 引入为count组件服务的reducer
    import count from "./count";
    // 引入Person组件服务的reducer
    import persons from "./person";
    // 汇总所有的reducer,变为一个整的reducer
    const allReducer = combineReducers({count,persons,
    });export default allReducer;
    
    • 组件中使用 action 方法时
    import { addPerson } from "../../redux/actions/person";
    const mapStateToProps = (state) => ({personList: state.persons,total: state.count,
    });const mapDispatchToProps = {addPerson,
    };export default connect(mapStateToProps, mapDispatchToProps)(Person);
    
  2. reducer文件夹中,新增一个index.js文件,专门用于汇总并暴露所有的reducer
    /*** 该文件用于汇总所有的reducer为一个总的reducer*/
    // 引入combineReducers,用于汇总所有的reducer
    import { combineReducers } from "redux";
    // 引入为count组件服务的reducer
    import count from "./count";
    // 引入Person组件服务的reducer
    import persons from "./person";
    // 汇总所有的reducer,变为一个整的reducer
    const allReducer = combineReducers({count,persons,
    });export default allReducer;
    
    store.js 文件中使用
    // 引入汇总之后的reducer
    import allReducer from "./reducers";const store = createStore(allReducer,applyMiddleware(thunk)
    );
    export default store;
    

九. react-redux 开发者工具的使用

  1. 浏览器拓展程序引入 Redux DevTools
    在这里插入图片描述

  2. 项目中安装 redux-devtools-extension
    yarn add redux-devtools-extension

  3. 配置store.js文件

    // 引入 redux-devtools-extension
    import { composeWithDevTools } from "redux-devtools-extension";
    const store = createStore(allReducer,composeWithDevTools(applyMiddleware(thunk))
    );
    

十. react-redux 正规使用流程

1. 准备工作,创建 redux 所需文件

src 文件夹下创建一个 redux 文件夹
redux 文件夹下创建 actions 文件夹、reducers 文件夹、constans.js 文件、store.js 文件
reducers 文件夹下创建 index.js 文件

redux 文件层级:

- src- redux- actions- reducers- index.js- constans.js- store.js
  • actions 文件夹
    用于为组件生成 action 对象。
  • reducers 文件夹
    (1)用于创建一个组件服务的 reducerreducer 的本质是一个函数。
    (2)reducer 函数会接收到两个参数,分别为:之前的状态(preState),动作对象(action)。
  • reducers/index.js 文件
    该文件用于汇总所有的 reducer 为一个总的 reducer
  • constans.js 文件
    (1)用于定义 action 对象中 type 类型的常量值。
    (2)目的只有一个:便于管理的同时防止程序员单词写错。
  • store.js 文件
    该文件专门用于暴露一个 store 对象,整个应用只有一个store 对象。

2. 安装 redux 所需的依赖,编写基础代码

  1. 安装 redux
    用于创建redux中最为核心的store对象
    yarn add redux react-redux
  2. 安装 redux-thunk
    用于支持异步 action
    yarn add redux-thunk
  3. 安装 redux-devtools-extension
    用于支持 react-redux 开发者工具的使用
    yarn add redux-devtools-extension
  • src/redux/reducers/index.js 文件修改
    // 引入combineReducers,用于汇总所有的reducer
    import { combineReducers } from "redux";// 汇总所有的reducer,变为一个整的reducer
    const allReducer = combineReducers({});export default allReducer;
    
  • src/redux/store.js 文件修改
    // 引入createStore,专门用于创建redux中最为核心的store对象
    import { createStore, applyMiddleware } from "redux";
    // 引入redux-thunk,用于支持异步action
    import thunk from "redux-thunk";
    // 引入 redux-devtools-extension
    import { composeWithDevTools } from "redux-devtools-extension";
    // 引入汇总之后的reducer
    import allReducer from "./reducers";const store = createStore(allReducer,composeWithDevTools(applyMiddleware(thunk))
    );
    export default store;
    
  • src/index.js 文件修改
    import React from "react";
    import ReactDOM from "react-dom/client";
    import App from "./App";
    import reportWebVitals from "./reportWebVitals";
    import { Provider } from "react-redux";
    import store from "./redux/store";const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render({/* 此处需要用 Provider 包裹 App,目的是让 App 所有的后代容器组件都能接收到store */}{/* 可代替下方 store.subscribe(),实现自动监听 */}store}>
    );
    // 监测redux中状态的改变, 若redux中的状态发生了改变,则重新渲染App组件
    // store.subscribe(() => {
    //   root.render(
    //     
    //       
    //     
    //   );
    // });
    reportWebVitals();
    

3. 编写组件功能

3.1 Count 组件 实例

实现一个数值 加减 的组件(Count 组件)

  1. src/redux/constants.js 文件修改,添加方法常量

    // 定义action对象中type类型的常量值
    export const INCREMENT = "increment";
    export const DECREMENT = "decrement";
    
  2. src/redux/actions 文件夹新增 count.js,对应 Count 组件action

    import { INCREMENT, DECREMENT } from "../constants.js";// 加
    // 简写方式
    // export const increment = (data) => ({ type: INCREMENT, data });
    // 正常方式
    export const increment = (data) => {return {type: INCREMENT,data,};
    };
    // 减
    export const decrement = (data) => {return {type: DECREMENT,data,};
    };
    
  3. src/redux/reducers 文件夹新增 count.js,对应 Count 组件reducer

    /*** 1. 该文件是用于创建一个为为Count组件服务的reducer,reducer的本质是一个函数* 2. reducer函数会接收到两个参数,分别为:之前的状态(preState),动作对象(action)*/
    import { DECREMENT, INCREMENT } from "../constants.js";const initState = 0; //初始化状态
    // 当第一次 preState 为 undefined 时,preState 赋值等于 initState
    export default function increment(preState = initState, action) {// 从 action 对象中获取:type,dataconst { type, data } = action;// 根据 type 决定加工数据switch (type) {case INCREMENT:return preState + data;case DECREMENT:return preState - data;default:return preState;}
    }
    
  4. src/redux/reducers/index.js 文件修改,添加合并 Count 组件reducer
    在这里插入图片描述

  5. Count 组件中 引入 connect 生成一个容器组件,并暴露。通过this.props....读取和操作状态。

    容器组件写法:

    export default connect((state) => ({ key: value }),//映射状态{ key: action方法, }//映射操作状态的方法
    )(UI组件);
    
    import React, { Component } from "react";
    import { connect } from "react-redux";
    import { increment, decrement } from "../../redux/actions/count";class Count extends Component {incrementNumber = () => {this.props.increment(1);};decrementNumber = () => {this.props.decrement(1);};render() {console.log(this.props);return (

    当前数值:{this.props.num}

    );} } /*** 映射状态,组件中需要使用的 reducer 状态* state.xxx key 对应 src/redux/reducers/index.js 中 allReducer 对应组件的 key*/ const mapStateToProps = (state) => ({ num: state.count }); // 映射操作状态的方法,组件中需要使用的事件方法 const mapDispatchToProps = {increment,decrement, }; // 使用connect()()创建并暴露一个Count的容器组件 export default connect(mapStateToProps, mapDispatchToProps)(Count);

3.2 Persons 组件 实例

实现一个人员信息列表 新增 功能(Persons 组件)
步骤同 3.1 Conut 组件实例 相同

  1. src/redux/constants.js 文件修改,添加方法常量

    // 定义action对象中type类型的常量值
    export const INCREMENT = "increment";
    export const DECREMENT = "decrement";export const ADD_PERSON = "add_person";
    
  2. src/redux/actions 文件夹新增 persons.js,对应 Persons 组件action

    import { ADD_PERSON } from "../constants.js";// 新增人员
    export const addPerson = (data) => ({ type: ADD_PERSON, data });
    
  3. src/redux/reducers 文件夹新增 persons.js,对应 Persons 组件reducer

    import { ADD_PERSON } from "../constants.js";const initState = [{id: 1,name: "小明",age: 18,},
    ];
    export default function addPerson(preState = initState, action) {const { type, data } = action;// 根据 type 决定加工数据switch (type) {case ADD_PERSON:return [data, ...preState];default:return preState;}
    }
    
  4. src/redux/reducers/index.js 文件修改,添加合并 Persons 组件reducer
    在这里插入图片描述

  5. Persons 组件 中 引入 connect 生成一个容器组件,并暴露。通过this.props....读取和操作状态。

    import React, { Component } from "react";
    import { connect } from "react-redux";
    // 引入 action
    import { addPerson } from "../../redux/actions/persons.js";class Persons extends Component {add = () => {const name = this.nameNode.value;const age = this.ageNode.value * 1;const personObj = {id: this.props.personList.length + 1,name,age,};this.props.addPerson(personObj);};render() {console.log(this.props);return (
    (cur) => (this.nameNode = cur)}type="text"placeholder="请输入姓名"/> (cur) => (this.ageNode = cur)}type="number"placeholder="请输入年龄"/> 
      {this.props.personList.map((v) => {return (
    • v.id}>姓名:{v.name},年龄:{v.age}
    • );})}
    );} } /*** 映射状态,组件中需要使用的 reducer 状态* state.xxx key 对应 src/redux/reducers/index.js 中 allReducer 对应组件的 key*/ const mapStateToProps = (state) => ({ personList: state.persons }); // 映射操作状态的方法,组件中需要使用的事件方法 const mapDispatchToProps = {addPerson, }; // 使用connect()()创建并暴露一个Persons的容器组件 export default connect(mapStateToProps, mapDispatchToProps)(Persons);

3.3 Count组件 和 Persons 组件 相互通信

  1. Count组件

    mapStateToProps 中映射 Person组件 的状态
    在这里插入图片描述
    render() 中渲染
    在这里插入图片描述

  2. Persons组件

    mapStateToProps 中映射 Count组件 的状态
    在这里插入图片描述

    render() 中渲染
    在这里插入图片描述

3.4 页面展示

在这里插入图片描述

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...