React|【Redux】如何实现多组件数据共享


文章目录

  • 多个组件数据共享
    • 项目结构
    • 效果展示
    • 总结

博主主页蜡笔雏田学代码
今天学习一下使用redux如何实现多组件共享数据
感兴趣的小伙伴一起来看看吧~
React|【Redux】如何实现多组件数据共享
文章图片

多个组件数据共享 我们之前学习的都是只有一个组件获取redux里的数据,也就是Count求和这个组件。但是redux在真实的使用场景中,肯定是有多个组件共享数据,才会使用redux进行状态管理。接下来使用多个组件通过redux实现数据共享。
我们创建一个Person组件,Person组件的数据也交给redux管理,这样Count组件和Person组件就可以实现数据共享。
项目结构 在redux文件夹下新创建两个文件夹actions和reducers。
React|【Redux】如何实现多组件数据共享
文章图片

效果展示 React|【Redux】如何实现多组件数据共享
文章图片

注意:Count组件的相关内容在前几篇文章中详细介绍了,此文就不再赘述了…
请阅读:Redux求和案例详解版教程
1??首先准备好一个Person组件:
src/containers/Person/index.jsx:
import React, { Component } from 'react' import { nanoid } from 'nanoid'export default class Person extends Component { addPerson = () => { const name = this.nameNode.value const age = this.ageNode.value const personObj = { id: nanoid(), name, age } console.log(personObj) }render() { return (
我是Person组件 this.nameNode = c} type="text" placeholder='输入名字' /> this.ageNode = c} type="text" placeholder='输入年龄' />
  • 名字1--年龄1
  • 名字2--年龄2
  • 名字3--年龄3
) } }

【React|【Redux】如何实现多组件数据共享】2??在constant.js文件里添加一个类型:
constant.js:
export const INCREMENT = 'increment' export const DECREMENT = 'decrement' + export const ADD_PERSON = 'add_person'

3??编写Person组件的action文件,用于创建action动作对象以供Person组件使用
/src/redux/actions/person.js:
import { ADD_PERSON } from '../constant'// 创建增加一个人的action动作对象 export const createAddPersonAction = personObj => ({ type: ADD_PERSON, data: personObj })

4??编写Person组件的reducer文件,用于创建一个为Person组件服务的reducer函数
/src/redux/reducers/person.js:
import { ADD_PERSON } from '../constant'//初始化人的列表 const initState = [{ id: '001', name: 'tom', age: 18 }] export default function personReducer(preState = initState, action) { const { type, data } = action switch (type) { case ADD_PERSON: //若是添加一个人 return [data, ...preState] default: return preState } }

此处的personReducer函数是一个纯函数
纯函数:
  1. 一类特别的函数: 只要是同样的输入(实参),必定得到同样的输出(返回)。一个函数的返回结果只依赖其参数,并且执行过程中没有副作用。
  2. 必须遵守以下一些约束:
    • 不得改写参数数据
      function demo(a){ a=9 }

    • 不会产生任何副作用,例如不能发送网络请求,输入和输出设备
    • 不能调用Date.now()或者Math.random()等不纯的方法
  3. redux的reducer函数必须是一个纯函数
    下面是错误写法:
    const initState = [{ id: '001', name: 'tom', age: 18 }] export default function personReducer(preState = initState, action) { const { type, data } = action switch (type) { case ADD_PERSON: //若是添加一个人 //此处不可以这样写,这样会导致preState被改写了, //personReducer就不是纯函数了, //会影响redux不能够识别状态的改变。 preState.unshift(data) return preState default: return preState } }

5??由于store.js中只引入了为Count组件服务的reducer,没有引入为Person组件服务的reducer,所以Person组件里的reducer根本没有运行,能为store效力的只有CountReducer。
若想要redux为多个组件服务,redux中存放了多个组件的状态,就需要用一个对象去存储redux中所有组件的状态,每一个组件存放在redux中的状态都是一组key: value。例如: Count组件: count: 0 ,Person组件: persons: []
合并reducer:需要引入一个API: combineReducers函数
/src/redux/store.js
/* 该文件专门用于暴露一个store对象,整个应用只有一个store对象 */ // 引入createStore,专门用于创建redux中最为核心的store对象 import { legacy_createStore as createStore, applyMiddleware, combineReducers } from 'redux'; // 引入为Count组件服务的reducer import countReducer from './reducers/count' // 引入为Person组件服务的reducer import personReducer from './reducers/person' // 引入redux-thunk,用于支持异步任务 import thunk from 'redux-thunk'// 汇总所有的reducer变为一个总的reducer // combineReducers调用时传入的对象就是redux帮我们保存的总的状态对象 const allReducer = combineReducers({ count: countReducer, persons: personReducer })// 暴露store export default createStore(allReducer, applyMiddleware(thunk))

将原先的countReducer与新引入的personReducer合并,并且将合并后的allReducer传递给createStore函数作为第一个参数,目的是将这两个组件的状态用一个对象包裹起来,再传给store。
6??Person组件里的状态已经存放在了redux中了,现在需要使用react-redux在Person组件里写Person的UI组件以及Person组件的容器组件。
src/containers/Person/index.jsx:
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.valuehttps://www.it610.com/article/= '' this.ageNode.valuehttps://www.it610.com/article/= '' }render() { return (
我是Person组件 this.nameNode = c} type="text" placeholder='输入名字' /> this.ageNode = c} type="text" placeholder='输入年龄' />
    { this.props.personArr.map((p) => { return
  • {p.name}--{p.age}
  • }) }
) } }export default connect( // 映射状态 state => ({ personArr: state.persons }), // 映射操作状态的方法 { dispatchAddPerson: createAddPersonAction } )(Person)

7??若要实现Count组件获取Person组件的状态,Person组件获取Count组件的状态
... 我是Person组件,上方组件求和为:{this.props.count} ... export default connect( // 映射状态 state => ({ personArr: state.persons, count: state.count }), // 映射操作状态的方法 { dispatchAddPerson: createAddPersonAction } )(Person)

... 我是Count组件,下方组件总人数为:{this.props.person} ... export default connect( state => ({ count: state.count, person: state.persons.length }), { jia: createIncrementAction, jian: createDecrementAction, jiaAsync: createIncrementAsyncAction } )(Count)

总结
1??定义一个Person组件,和Count组件通过redux共享数据。
2??为Person组件编写:reducer、action,配置constant常量。
3??重点:Person的reducer和Count的Reducer要使用combineReducers进行合并。合并后的总状态是一个对象!!!
4??交给store的是总reducer,最后注意在组件中取出状态的时候,记得“取到位”。
今天的分享就到这里啦? \textcolor{red}{今天的分享就到这里啦?} 今天的分享就到这里啦?

原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下

点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

??收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

??评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

    推荐阅读