上篇文章初步了解和学习了react-redux的原理和组件拆分 今天探索一下react-redux基本使用以及对求和案例的代码优化 感兴趣的小伙伴一起来看看吧!🤞
?react-redux基本使用
依旧对求和案例进行分析:
根据react-redux模型图,实现了Count的容器组件与Count的UI组件的联系,接下来要实现容器组件给UI组件传递 redux中所保存的状态以及操作状态的方法,要借助props 。
但是不能像原先父子组件传参利用标签的方式传递,比如:
<A>
<B a='1' b='2'/>
<A/>
那么如何在容器组件(父组件)向UI组件传递参数呢?
由于父子组件关系是靠connect形成的,所以connect函数在第一次调用的时候要传入两个参数,参数必须是函数类型的,这样react-redux库就帮你调用这两个函数,一个函数返回值作为状态,另一个函数返回值作为操作状态的方法。
export default connect(mapStateToProps, mapDispatchToProps)(CountUI)
mapStateToProps()函数的返回值作为 状态 传递给了UI组件,函数返回的是一个对象,mapStateToProps函数返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value。
由于要获取redux里的状态,就要store.getState(),就要在容器组件里引入store,但是之前已经在上层App.jsx里向容器组件传了store,就不需要自己引入了,这里也不需要我们自己去获取状态,react-redux帮我们调mapStateToProps()函数时,已经帮我们把状态传过去了,只需要mapStateToProps(state)接收一下即可。
function mapStateToProps(state) {
return { count: state }
}
这样UI组件就可以通过 this.props 接收到 状态:
<h1>当前求和为:{this.props.count}</h1>
mapDispatchToProps()函数的返回值作为 操作状态的方法 传递给了UI组件,函数返回的是一个对象,mapDispatchToProps函数返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value。
由于要实现加这个运算,就要在jia这个回调函数里通知redux执行加法,就要调用store.dispatch(action)这个方法,这里又要引入store操作状态,但是这里也不需要store调用dispatch方法,react-redux帮我们把dispatch()方法传过去了,直接用即可。
import {
createIncrementAction,
createDecrementAction,
createIncrementAsyncAction
} from '../../redux/count_action'
function mapDispatchToProps(dispatch) {
return {
jia: (number) => {
dispatch(createIncrementAction(number))
},
jian: (number) => {
dispatch(createDecrementAction(number))
},
jiaAsync: (number, time) => {
dispatch(createIncrementAsyncAction(number, time))
}
}
}
这样UI组件就可以通过 this.props 接收到 操作状态的方法:
increment = () => {
const { value } = this.selectNumber
this.props.jia(value * 1)
}
decrement = () => {
const { value } = this.selectNumber
this.props.jian(value * 1)
}
incrementIfOdd = () => {
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)
}
src=> components=> Count => index.jsx:
import React, { Component } from 'react'
export default class Count extends Component {
increment = () => {
const { value } = this.selectNumber
this.props.jia(value * 1)
}
decrement = () => {
const { value } = this.selectNumber
this.props.jian(value * 1)
}
incrementIfOdd = () => {
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() {
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.incrementIfOdd}>当前求和为奇数再加</button>
<button onClick={this.incrementAsync}>异步加</button>
</div>
)
}
}
src=> containers=> Count => index.jsx:
import CountUI from '../../components/Count'
import {
createIncrementAction,
createDecrementAction,
createIncrementAsyncAction
} from '../../redux/count_action'
import { connect } from 'react-redux'
function mapStateToProps(state) {
return { count: state }
}
function mapDispatchToProps(dispatch) {
return {
jia: (number) => {
dispatch(createIncrementAction(number))
},
jian: (number) => {
dispatch(createDecrementAction(number))
},
jiaAsync: (number, time) => {
dispatch(createIncrementAsyncAction(number, time))
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(CountUI)
?求和案例_react-redux基本使用总结
1??明确两个概念:
- UI组件:不能使用任何redux的api,只负责页面的呈现、交互等。
- 容器组件:负责和redux通信,将结果交给UI组件。
2??如何创建一个容器组件———依靠react-redux的connect函数
connect(mapStateToProps,mapDispatchToProps)(UI组件)
- mapStateToProps:映射状态,返回值是一个对象
- mapDispatchToProps:映射操作状态的方法,返回值是一个对象
3?? 备注:容器组件中的store是靠props传进去的,而不是在容器组件中直接引入。
?优化1:简写mapDispatch
优化前:
function mapStateToProps(state) {
return { count: state }
}
优化后:
const mapStateToProps = state => ({ count: state })
优化前:
function mapDispatchToProps(dispatch) {
return {
jia: (number) => {
dispatch(createIncrementAction(number))
},
jian: (number) => {
dispatch(createDecrementAction(number))
},
jiaAsync: (number, time) => {
dispatch(createIncrementAsyncAction(number, time))
}
}
}
优化后:
const mapDispatchToProps = dispatch => (
{
jia: number => dispatch(createIncrementAction(number)),
jian: number => dispatch(createDecrementAction(number)),
jiaAsync: (number, time) =>
dispatch(createIncrementAsyncAction(number, time))
}
)
再优化后:
import CountUI from '../../components/Count'
import {
createIncrementAction,
createDecrementAction,
createIncrementAsyncAction
} from '../../redux/count_action'
import { connect } from 'react-redux'
export default connect(
state => ({ count: state }),
dispatch => (
{
jia: number => dispatch(createIncrementAction(number)),
jian: number => dispatch(createDecrementAction(number)),
jiaAsync: (number, time) =>
dispatch(createIncrementAsyncAction(number, time))
}
)
)(CountUI)
mapDispatchToProps的简写:
export default connect(
state => ({ count: state }),
{
jia: createIncrementAction,
jian: createDecrementAction,
jiaAsync: createIncrementAsyncAction
}
)(CountUI)
分析mapDispatchToProps的简写
{
jia: createIncrementAction,
jian: createDecrementAction,
jiaAsync: createIncrementAsyncAction
}
Count的UI组件里调用了jia函数,传递了用户选择的参数,然后在容器组件里调用了createIncrementAction方法,返回值是一个action对象,react-redux帮我们自动dispatch 了。
mapDispatchToProps可以写成一个普通的函数 ,也可以是一个对象 。
react-redux还有一个优势:不用自己监测redux的状态是否发生了变化,内部的所有逻辑全部交给容器组件来完成,避免污染整个app组件。
?优化2:Provider组件的使用
App.jsx:
import React, { Component } from 'react'
import Count from './containers/Count'
import store from './redux/store'
export default class App extends Component {
render() {
return (
<div>
{}
<Count store={store} />
</div>
)
}
}
当项目中有多个容器组件时,每次都要给容器组件传递store,这样不太方便,所以:我们可以在index.js入口文件里引入react-redux里的一个API——Provider 。
把所有容器组件都需要的store交给Provider,Provider会自动分析整个项目里所有的容器组件,把store传给每一个需要store的容器组件。
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'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
{}
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
)
?优化3:整合UI组件与容器组件
前面两个优化,我们分别从代码层面和API层面进行了优化。在这里,我们将在文件层面对UI组件和容器组件进行优化。
由于我们学习了react-redux库,要求为组件分别写成UI组件和容器组件。那么如果在整个应用中,有20个组件需要和redux打交道,那么我们就需要写40个组件…可想而知,这样写是不行的,我们可以作出一些优化:
可以将UI组件和容器组件整合在同一个文件夹里。
/src/containers/Count/index.jsx:
import React, { Component } from 'react'
import {
createIncrementAction,
createDecrementAction,
createIncrementAsyncAction
} from '../../redux/count_action'
import { connect } from 'react-redux'
class Count extends Component {
increment = () => {
const { value } = this.selectNumber
this.props.jia(value * 1)
}
decrement = () => {
const { value } = this.selectNumber
this.props.jian(value * 1)
}
incrementIfOdd = () => {
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() {
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.incrementIfOdd}>当前求和为奇数再加</button>
<button onClick={this.incrementAsync}>异步加</button>
</div>
)
}
}
export default connect(
state => ({ count: state }),
{
jia: createIncrementAction,
jian: createDecrementAction,
jiaAsync: createIncrementAsyncAction
}
)(Count)
?求和案例_react-redux优化总结
1?? 容器组件和UI组件整合成一个文件
2?? 无需自己给容器组件传递store,给
<
<
<App/>包裹一个
<
<
<Provider store={store}>即可。
3?? 使用了react-redux后也不用再自己监测redux中状态的改变了,容器组件可以自动完成这个工作。
4?? mapDispatchToProps也可以简单的写成一个对象。
5?? 一个组件要和redux“打交道”要经过哪几步?
-
定义好UI组件—不暴露 -
引入connect生成一个容器组件,并暴露,写法如下: connect(
state => ({key:value}),
{key:xxxxAction}
)(UI组件)
-
在UI组件中通过this.props.xxxxxx读取和操作状态
今天的分享就到这里啦?
\textcolor{red}{今天的分享就到这里啦?}
今天的分享就到这里啦?
原创不易,还希望各位大佬支持一下
\textcolor{blue}{原创不易,还希望各位大佬支持一下}
原创不易,还希望各位大佬支持一下
🤞
点赞,你的认可是我创作的动力!
\textcolor{green}{点赞,你的认可是我创作的动力!}
点赞,你的认可是我创作的动力!
??
收藏,你的青睐是我努力的方向!
\textcolor{green}{收藏,你的青睐是我努力的方向!}
收藏,你的青睐是我努力的方向!
??
评论,你的意见是我进步的财富!
\textcolor{green}{评论,你的意见是我进步的财富!}
评论,你的意见是我进步的财富!
|