上一个求和案例只用了一个组件,现在看看redux如何实现多个组件之间的数据共享。
①定义一个Person组件,和Count组件通过redux共享数据
②为Person组件编写:reducer、action,配置constant常量
③使用combineReducers对Count和Person的Reducer进行合并,合并后的总状态是一个对象。
④交给store的是总reducer
/src/containers/Count/index.jsx
- import {connect} from 'react-redux'
- import React, { Component } from 'react'
- // 引入action
- import {
- increment,
- decrement,
- incrementAsync
- } from '../../redux/actions/count'
-
- // 定义CountUI组件
- class Count extends Component {
- increment=()=>{
- const {value} = this.selectNumer
- this.props.increment(value*1)
- }
- decrement=()=>{
- const {value} = this.selectNumer
- this.props.decrement(value*1)
- }
- incrementAsync=()=>{
- const {value} = this.selectNumer
- this.props.incrementAsync(value*1,500)
- }
- render() {
- return (
- <div>
- <h1>当前求和为:{this.props.count},下方组件人数:{this.props.personCount}h1>
- <select ref={c => this.selectNumer = c}>
- <option value="1">1option>
- <option value="2">2option>
- <option value="3">3option>
- select>
- <button onClick={this.increment}>+button>
- <button onClick={this.decrement}>-button>
- <button onClick={this.incrementAsync}>异步加button>
- div>
- )
- }
- }
- // 创建并暴露一个Count的容器组件
- export default connect(
- state => ({count: state.count,personCount:state.persons.length}),
- {
- increment,
- decrement,
- incrementAsync
- }
- )(Count)
/src/containers/Person/index.jsx
- import React, { Component } from 'react'
- import { nanoid } from 'nanoid'
- import { connect } from 'react-redux';
- import { addPerson } 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.addPerson(personObj)
- }
- render() {
- return (
- <div>
- <h1>上方组件的求和为:{this.props.Count}h1>
- <input ref={c=>this.nameNode = c} type="text" placeholder='输入名字' />
- <input ref={c=>this.ageNode = c} type="text" placeholder='年龄' />
- <button onClick={this.addPerson}>添加button>
- <ul>
- {
- this.props.persons.map((p) => {
- return <li key={p.id}>{p.name}--{p.age}li>
- })
- }
- ul>
- div>
- )
- }
- }
-
- export default connect(
- state => ({persons: state.persons,Count:state.count}),
- {
- addPerson
- }
- )(Person)
/src/redux/actions/count.js
- /*
- 该文件专门为Count组件生成action对象
- */
- import { INCREMENT, DECREMENT } from "../constant";
-
- // 同步action,就是指action的值为一般object类型的对象
- export const increment = data => ({type:INCREMENT,payload: data})
- export const decrement = data => ({type:DECREMENT,payload: data})
-
- // 异步action,就是指action的值为函数
- export const incrementAsync = (data, time) => {
- return (dispatch)=>{
- setTimeout(()=>{
- dispatch(increment(data))
- },time)
- }
- }
/src/redux/reducers/count.js/src/redux/actions/person.js
- import {ADD_PERSON} from '../constant'
-
- export const addPerson = personObj => ({type:ADD_PERSON,payload:personObj})
/src/redux/reducers/index.js
- /*
- 该文件用于汇总所有reducer为一个总的reducer
- */
- import {combineReducers} from '@reduxjs/toolkit'
- import count from './count' //引入为Count组件服务的reducer
- import persons from './person' //引入为Person组件服务的reducer
-
- export default combineReducers({
- count,
- persons
- })
/src/redux/reducers/count.js
- /*
- 该文件是用于创建一个为Count组件服务的reducer
- */
- import { INCREMENT,DECREMENT } from "../constant"
-
- const initState = 0;
- export default function countReducer(preState=initState, action) {
- const {type, payload} = action;
- switch(type) {
- case INCREMENT:
- return preState+payload;
- case DECREMENT:
- return preState-payload;
- default:
- return preState;
- }
- }
/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,payload} = action
- switch(type) {
- case ADD_PERSON:
- return [payload,...preState]
- default:
- return preState
- }
- }
/src/redux/constant.js
- /*
- 该模块用于定义action对象中type类型的常量值
- */
- export const INCREMENT = 'increment'
- export const DECREMENT = 'decrement'
- export const ADD_PERSON = 'add_person'
/src/redux/store.js
- /*
- 该文件用于暴露一个store对象
- */
- import {configureStore} from '@reduxjs/toolkit'
- import reducer from './reducers'
-
- export default configureStore({ reducer: reducer })
/src/App.jsx
- import Count from "./containers/Count"; //引入Count的容器组件
- import Person from "./containers/Person" //引入Person的容器组件
-
- function App() {
- return (
- <div>
- <Count/>
- <hr />
- <Person />
- div>
- );
- }
-
- export default App;
/src/index.js
- import React from 'react';
- import ReactDOM from 'react-dom/client';
- import App from './App';
- import store from './redux/store';
- import { Provider } from 'react-redux'; // provider会自动帮容器组件传store
-
- const root = ReactDOM.createRoot(document.getElementById('root'));
- root.render(
- <Provider store={store}>
- <App />
- Provider>
- );
效果
全局安装serve库,并配置一下环境变量
npm i serve -g
将上面的项目打包,在项目根目录下面执行如下指令,会生成一个build文件夹
npm run build
在生产环境运行该项目,serve指令后面跟的build文件夹的路径
serve build