• 【react-redux】多个组件数据共享


    在这里插入图片描述

    欢迎来到我的博客
    📔博主是一名大学在读本科生,主要学习方向是前端。
    🍭目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏
    🛠目前正在学习的是🔥 R e a c t 框架 React框架 React框架🔥,中间穿插了一些基础知识的回顾
    🌈博客主页👉codeMak1r.小新的博客

    本文被专栏【React–从基础到实战】收录

    🕹坚持创作✏️,一起学习📖,码出未来👨🏻‍💻!
    在这里插入图片描述

    多个组件数据共享

    我们之前讲解的一直都是只有一个组件需要向redux读取状态,也就是Count这个求和组件。那么我们在实际使用redux的场景中,当然是有很多组件一起共享数据才需要使用到redux进行状态管理啦,现在我们就来看看多个组件通过redux实现数据共享的场景吧~

    现在我们创建一个Person组件,同样的,Person组件的数据也交给redux管理。此时,Count组件也可以从redux中读取到Person组件的数据,Person组件也可以从redux中读取到Count组件之前存放在redux中的数据。是不是很方便呢?这就是redux集中式的状态管理中的多个组件的数据共享。

    项目结构:

    src
    ├─App.jsx
    ├─index.js
    ├─redux
    |   ├─constant.js
    |   ├─store.js
    |   ├─reducers
    |   |    ├─count.js
    |   |    └person.js
    |   ├─actions
    |   |    ├─count.js
    |   |    └person.js
    ├─containers
    |     ├─Person
    |     |   └index.jsx
    |     ├─Count
    |     |   └index.jsx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    项目展示:

    在这里插入图片描述

    ⚠️注意:Count组件部分内容已在前几篇文章中,在本文中注重的是新增的Person组件与之前的Count组件共享状态。

    阅读顺序:
    【Redux工作流程】
    【异步action】
    【react-redux基本使用与优化】

    1. 首先在constant.js中添加我们在Person组件中需要使用的类型:
    export const INCREMENT = 'increment'
    export const DECREMENT = 'decrement'
    + export const ADD_PERSON = 'add_person'
    
    • 1
    • 2
    • 3

    该模块是用于定义action对象中type类型的常量模块,便于管理的同时避免程序员单词拼写出错。

    1. 编写Person组件的action文件,用于创建action动作对象以供Person组件使用:

    /src/redux/actions/person.js

    /* 
      该文件专门为Person组件生成action动作对象
    */
    import { ADD_PERSON } from "../constant";
    // 创建增加一个person的action动作对象
    export const createAddPersonAction = personObj => ({ type: ADD_PERSON, data: personObj })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 编写Person组件的reducer文件,用于创建一个为Person组件服务的reducer函数

    /src/redux/reducers/person.js

    /* 
      1.该文件用于创建一个为Person组件服务的reducer函数
      2.reducer函数会接收到两个参数,分别为之前的状态(prevState)和动作对象(action)
    */
    import { ADD_PERSON } from "../constant";
    const initState = [{ id: 001, name: 'tom', age: 18 }]
    export default function personReducer(prevState = initState, action) {
      const { type, data } = action
      switch (type) {
        case ADD_PERSON:
          return [data, ...prevState]
        default:
          return prevState
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. redux若只为一个组件服务,store内部存储的数据不需要任何的标识。但是store中若存放了多个组件的状态,那么就需要用一个对象将所有的状态囊括起来,每个状态都是一组key:value值。

    比如,Count组件存储的状态为:count:0。Person组件存储的状态为:persons:[]

    /src/redux/store.js

    - import { legacy_createStore as createStore, applyMiddleware } from 'redux';
    // 引入combineReducers,用于合并reducer
    + import { legacy_createStore as createStore, applyMiddleware, combineReducers } from 'redux';
    import countReducer from './reducers/count'
    // 引入为Person组件服务的reducer
    + import personReducer from './reducers/person';
    import thunk from 'redux-thunk'
    
    + // 合并reducer
    + const allReducer = combineReducers({
    +   count: countReducer,
    +   persons: personReducer
    + })
    // 暴露store
    - export default createStore(countReducer, applyMiddleware(thunk))
    + export default createStore(allReducer, applyMiddleware(thunk))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在原先的store中只存放了一个Count组件的状态数据,现在新增了Person组件需要使用redux,那么就应该对store.js进行一些修改。

    在store.js文件中,从redux中新引入combineReducers函数用于合并reducer;

    引入为Person组件服务的reducer;

    将原先的countReducer与新引入的personReducer合并,并且将合并后的allReducer传递给createStore函数作为第一个参数,目的是将这两个组件的状态用一个对象包裹起来,再传给store。

    1. Person组件已经与redux建立起了联系,那么现在可以在Person组件中书写Person的UI组件以及Person的容器组件(使用react-redux)。

      import React, { Component } from 'react'
      import { nanoid } from 'nanoid'
      import { connect } from 'react-redux'
      import { createAddPersonAction } from '../../redux/actions/person'
      
      class Person extends Component {
      
        addPerson = () => {
          const name = this.nameNode.value
          const age = this.ageNode.value
          const personObj = { id: nanoid(), name, age }
          this.props.dispatchAddPerson(personObj)
          this.nameNode.value = ''
          this.ageNode.value = ''
        }
      
        render() {
          return (
            <div>
              <h2>我是Person组件,上方组件求和为:{this.props.count}</h2>
              <input ref={currentNode => this.nameNode = currentNode} 
                     type="text" placeholder='输入名字' />
              <input ref={currentNode => this.ageNode = currentNode} 
                     type="text" placeholder='输入年龄' />
              <button onClick={this.addPerson}>添加</button>
              <ul>
                {
                  this.props.personArr.map(personObj => {
                    return <li key={personObj.id}>{personObj.name}---{personObj.age}</li>
                  })
                }
              </ul>
            </div>
          )
        }
      }
      export default connect(
        state => ({ personArr: state.persons, count: state.count }),
        { dispatchAddPerson: createAddPersonAction }
      )(Person)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
    2. 同时修改Count组件内容,使Count组件可以显示Person组件的人数。

      <h2>我是Count组件,下方组件总人数为:{this.props.person}</h2>
      //
      //
      export default connect(
        state => ({ count: state.count, person: state.persons.length }),
        {
          jia: createIncrementAction,
          jian: createDecrementAction,
          jiaAsync: createIncrementAsyncAction
        }
      )(Count)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      注意:关于connect()()函数详解内容,点击:<react-redux>基本使用与优化

    总结:

    1. 定义一个Person组件,和Count组件通过redux共享数据;
    2. 为Person组件编写:reducer、action,配置constant常量;
    3. 重点:Person的reducer和Count的reducer要使用combineReducers进行合并,合并后的总状态是一个对象;
    4. 交给store的是总reducer。
  • 相关阅读:
    【小航的算法日记】数组
    Linux系统调试篇——GDBSERVER远程调试
    深度学习_目标检测_SPP(Spatial Pyramid Pooling)详解
    代码随想录算法训练营第五十五天| LeetCode647. 回文子串、516.最长回文子序列
    vue实现div拖拽
    《银行法律法规》三、银行管理——4、资本管理
    健康防猝指南2:饮食健康
    MFC Windows 程序设计[228]之拖拽列表(附源码)
    PAT Head of a Gang(字符串转化成数字,图的dfs)
    八、Thymeleaf链接表达式
  • 原文地址:https://blog.csdn.net/Svik_zy/article/details/126078947