目录
上一个求和案例只用了一个组件,现在看看redux如何实现多个组件之间的数据共享。
1.步骤
①定义一个Person组件,和Count组件通过redux共享数据 ②为Person组件编写:reducer、action,配置constant常量 ③使用combineReducers对Count和Person的Reducer进行合并,合并后的总状态是一个对象。 ④交给store的是总reducer
2.案例
/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">1</option>
<option value="2">2</option>
<option value="3">3</option>
</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>
);
效果
3.打包项目
全局安装serve库,并配置一下环境变量
npm i serve -g
将上面的项目打包,在项目根目录下面执行如下指令,会生成一个build文件夹
npm run build
在生产环境运行该项目,serve指令后面跟的build文件夹的路径
serve build
|