欢迎来到我的博客
📔博主是一名大学在读本科生,主要学习方向是前端。
🍭目前已经更新了【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
项目展示:
⚠️注意:Count组件部分内容已在前几篇文章中,在本文中注重的是新增的Person组件与之前的Count组件共享状态。
- 首先在
constant.js
中添加我们在Person组件中需要使用的类型:
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
+ export const ADD_PERSON = 'add_person'
该模块是用于定义action对象中type类型的常量模块,便于管理的同时避免程序员单词拼写出错。
- 编写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 })
- 编写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
}
}
- 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))
在原先的store中只存放了一个Count组件的状态数据,现在新增了Person组件需要使用redux,那么就应该对store.js进行一些修改。
在store.js文件中,从redux中新引入combineReducers函数用于合并reducer;
引入为Person组件服务的reducer;
将原先的countReducer与新引入的personReducer合并,并且将合并后的allReducer传递给createStore函数作为第一个参数,目的是将这两个组件的状态用一个对象包裹起来,再传给store。
-
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)
-
同时修改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)
注意:关于connect()()函数详解内容,点击:<react-redux>基本使用与优化
总结:
- 定义一个Person组件,和Count组件通过redux共享数据;
- 为Person组件编写:reducer、action,配置constant常量;
- 重点:Person的reducer和Count的reducer要使用combineReducers进行合并,合并后的总状态是一个对象;
- 交给store的是总reducer。