2.react-redux的使用
npm install --save react-redux
1.基本使用
containers/Count.jsx
-- 容器组件 -- 用于传递 redux保存的状态和操作状态的方法 到 UI组件中
// 引入Count的UI组件
import CounUI from "../../components/Count";
import {
createIncrementAction,
createDecrementAction,
createIncrementAsyncAction
} from "../../redux/count_action";
// 引入connect用于连接UI组件与redux
import {connect} from "react-redux";
// 1.mapStateToProps函数的返回的是一个对象,
// 2.返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value--状态
// 3.mapStateToProps用于传递状态
// 4.容器连接UI组件时就已经把store的初始状态state传递给mapStateToProps函数
const mapStateToProps = (state) => {
return {count: state}
}
// 1.mapDispatchToProps函数的返回的是一个对象,
// 2.返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value--操作状态的方法
// 3.mapDispatchToProps用于传递操作状态的方法
// 4.容器连接UI组件时react-redux就已经把store的dispatch方法传递给mapDispatchToProps函数
const mapDispatchToProps = (dispatch) => {
return {
jia: number => dispatch(createIncrementAction(number)),
jian: number => dispatch(createDecrementAction(number)),
jiaAsync: (number,time) => dispatch(createIncrementAsyncAction(number, time)),
}
}
// 使用connect()()创建并暴露一个Count容器组件
export default connect(mapStateToProps, mapDispatchToProps)(CounUI)
components/Count.jsx
-- UI组件 -- 通过this.props接收 redux保存的状态和操作状态的方法
import React, {Component} from 'react';
class CountUI extends Component {
increment = () => {
const {value} = this.selectNumber
// 使用容器组件传递的方法
this.props.jia(value*1)
}
decrement = () => {
const {value} = this.selectNumber
this.props.jian(value*1)
}
incrementOdd = () => {
const {value} = this.selectNumber
// 使用容器组件传递的状态
if (this.props.count % 2 !== 0){
this.props.jia(value*1)
}
}
incrementAsync = () => {
const {value} = this.selectNumber
this.props.jiaAsync(value*1, 500)
}
render() {
// console.log('UI组件接收到的props是:',this.props)
return (
<div>
<h1>当前求和为: {this.props.count}</h1>
<select ref={c => this.selectNumber = 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.incrementOdd}>当前求和为奇数加</button>
<button onClick={this.incrementAsync}>异步加</button>
</div>
);
}
}
export default CountUI;
2.优化
将UI组件写到容器组件下:
import React, {Component} from 'react';
// 引入connect用于连接UI组件与redux
import {connect} from "react-redux";
import {
createIncrementAction,
createDecrementAction,
createIncrementAsyncAction
} from "../../redux/count_action";
// 定义UI组件
class Count extends Component {
increment = () => {
const {value} = this.selectNumber
this.props.jia(value*1)
}
decrement = () => {
const {value} = this.selectNumber
this.props.jian(value*1)
}
incrementOdd = () => {
const {value} = this.selectNumber
if (this.props.count % 2 !== 0){
this.props.jia(value*1)
}
}
incrementAsync = () => {
const {value} = this.selectNumber
this.props.jiaAsync(value*1, 500)
}
render() {
// console.log('UI组件接收到的props是:',this.props)
return (
<div>
<h1>当前求和为: {this.props.count}</h1>
<select ref={c => this.selectNumber = 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.incrementOdd}>当前求和为奇数加</button>
<button onClick={this.incrementAsync}>异步加</button>
</div>
);
}
}
// 映射状态
// const mapStateToProps = state => ({count: state})
// 映射操作状态的方法
// const mapDispatchToProps = dispatch => (
// {
// jia: number => dispatch(createIncrementAction(number)),
// jian: number => dispatch(createDecrementAction(number)),
// jiaAsync: (number,time) => dispatch(createIncrementAsyncAction(number, time)),
// }
// )
// 使用connect()()创建并暴露一个Count容器组件
export default connect(
state => ({count: state}),
// mapDispatchToProps的一般写法
// dispatch => ({
// jia: number => dispatch(createIncrementAction(number)),
// jian: number => dispatch(createDecrementAction(number)),
// jiaAsync: (number,time) => dispatch(createIncrementAsyncAction(number, time)),
// })
// mapDispatchToProps的简写方法
// 简写不需要写dispatch,react-redux会自动分发
{
jia: createIncrementAction,
jian: createDecrementAction,
jiaAsync: createIncrementAsyncAction,
}
)(Count)
在index.js中:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import store from "./redux/store";
import {Provider} from "react-redux";
ReactDOM.render(
// Provider专门为多个容器组件传递store,不用每个容器组件单独传store
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
// 监测redux中状态的变化,只要redux中状态发生变化,就调用render重新渲染
// 使用react-redux就不需要再监测了,redux发生状态就会自动渲染
// store.subscribe(()=>{
// ReactDOM.render(<App />, document.getElementById('root'))
// })
3.数据共享
多个容器组件之间数据的共享
由于是多个容器组件,那就存在多个不同的reducer,
// 引入 combineReducers,用于汇总多个reducer
import { combineReducers} from "redux";
// 引入为Count组件服务的reducer
import count from "./count";
// 引入为Person组件服务的reducer
import persons from "./person";
// combineReducers作用:汇总所有的reducer变成一个总得reducer
const allReducer = combineReducers({
count,
persons,
})
export default allReducer
在store.js中使用allReducer
export default createStore(allReducer, composeWithDevTools(applyMiddleware(thunk)))
Count.jsx
import React, {Component} from 'react';
// 引入connect用于连接UI组件与redux
import {connect} from "react-redux";
import {
increment,
decrement,
incrementAsync
} from "../../redux/actions/count";
// 定义UI组件
class Count extends Component {
increment = () => {
const {value} = this.selectNumber
this.props.increment(value * 1)
}
decrement = () => {
const {value} = this.selectNumber
this.props.decrement(value * 1)
}
incrementOdd = () => {
const {value} = this.selectNumber
if (this.props.count % 2 !== 0) {
this.props.increment(value * 1)
}
}
incrementAsync = () => {
const {value} = this.selectNumber
this.props.incrementAsync(value * 1, 500)
}
render() {
// console.log('UI组件接收到的props是:',this.props)
return (
<div>
<h2>我是Count组件</h2>
<h4>下方人总数为:{this.props.personsCount}</h4>
<h1>当前求和为: {this.props.count}</h1>
<select ref={c => this.selectNumber = 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.incrementOdd}>当前求和为奇数加</button>
<button onClick={this.incrementAsync}>异步加</button>
</div>
);
}
}
// 使用connect()()创建并暴露一个Count容器组件
// 由于用了合并reducer方法,所以state变成了一个对象
export default connect(
state => ({
count: state.count,
personsCount:state.persons.length}), // 在Count中使用Person的数据
{
increment,
decrement,
incrementAsync,
}
)(Count)
Person.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)
this.nameNode.value = ''
this.ageNode.value = ''
}
render() {
return (
<div>
<h2>我是Person组件</h2>
<h4>上方求和为{this.props.count}</h4>
<input ref={c=>this.nameNode = c} type="text" placeholder='输入名字'/>
<input ref={c=>this.ageNode = c} type="text" placeholder='输入年龄'/>
<button onClick={this.addPerson}> ADD</button>
<ul>
{
this.props.persons.map(ren=>{
return (
<li key={ren.id}>
{ren.name}---{ren.age}
</li>
)
})
}
</ul>
</div>
);
}
}
export default connect(
state=>({
persons:state.persons,
count:state.count}), // 在Person中使用Count的数据
{addPerson}
)(Person);