React--Redux②(connect函数原理)
connect实现原理
connect
的作用就是负责连接React
和Redux
connect
底层本质是高阶函数 高阶组件,即connect
函数接收函数作为参数,首先返回一个函数,返回的函数中又返回了组件,大致结构如下:
// connent.js
import { PureComponent } from "react";
import store from '../store';
/**
* @param {Function} mapStateToProps 用于映射store中各模块state的数据
* @param {Function} mapActionToProps 用于映射store中各模块的action
* @return {Function} 高阶组件
*/
// 接收函数作为参数
export function connent(mapStateToProps, mapActionToProps) {
// 返回函数
return function(Component) {
// 该函数返回组件
return class extends PureComponent {
render() {
return <Component {...this.props}/>
}
}
}
}
简单封装
- 将
state
和action
添加到组件的props
中
import store from '../store';
export function connent(mapStateToProps, mapActionToProps) {
return function(Component) {
return class extends PureComponent {
render() {
// mapStateToProps函数:(state) => ({})
// 这里调用mapStateToProps并传入state,拿到mapStateToProps中映射的数据
const stateObj = mapStateToProps(store.getState());
// 同理
const actionObj = mapActionToProps(store.dispatch)
// 将state和action添加到组件的props中
return <Component {...this.props} {...stateObj} {...actionObj}/>
}
}
}
}
- 在返回的新组件中监听
state
的变化
import store from '../store';
export function connent(mapStateToProps, mapActionToProps) {
return function(Component) {
return class extends PureComponent {
constructor() {
super()
// 拿到映射的state
this.state = mapStateToProps(store.getState())
}
componentDidMount() {
this.unsubcribe = store.subscribe(() => {
// 因为PureComponent内部会作浅层比较,所以将整个state更新
this.setState(mapStateToProps(store.getState()))
})
}
// 取消监听
componentWillUnmount() {
this.unsubcribe()
}
render() {
const stateObj = mapStateToProps(store.getState());
const actionObj = mapActionToProps(store.dispatch)
return <Component {...this.props} {...stateObj} {...actionObj}/>
}
}
}
}
解耦store
- 上面的做法有一点不好的是,假如把这个自定义的
connect
函数发布到NPM
仓库中,其他人安装后并没有办法使用,因为其他人的store
路径不一定是../store
- 这是因为
connect
函数和store
耦合度太高,所以需要将store
解耦
使用
context
的方式使用store
- 使用
React.CreateContext
对Store
创建一个上下文
// hoc/StoreContext.js
import { createContext } from 'react';
export const StoreContext = createContext();
- 新建一个入口文件,将
StoreContext
和connect
暴露
// index.js
export * from './StoreContext';
export * from './connect'
- 使用
<StoreContext.Provider>
对App
根组件进行包裹,共享store
import { StoreContext } from './hoc';
<StoreContext.Provider value={store}>
<App />
</StoreContext.Provider>
- 将
connect
函数中获取store
的方式改为从this.context
中获取
// import store from '../store';
import { StoreContext } from './StoreContext';
// 重写组件的contextType
static contextType = StoreContext;
constructor(props, context) { // 拿到当前context
super(props)
this.state = mapStateToProps(context.getState())
}
// 其他原本的 store 改为 this.context
// 如store.getState() → this.context.getState()
简单使用
- 最后在组件中就可以使用自己封装的
connect
函数了,和react-redux
一致
import { PureComponent } from 'react';
import { connect } from '../src/hoc';
import { addNum } from './store/modules/counter';
class App extends PureComponent {
render() {
const { num, addNum } = this.props
return (
<div>
<h2>App Count: {num}</h2>
<div className='button-box'>
<button onClick={e => addNum(1)}> 1</button>
<button onClick={e => addNum(5)}> 5</button>
<button onClick={e => addNum(10)}> 10</button>
</div>
</div>
)
}
}
const mapStateToProps = (state) => ({
num: state.counter.num
})
const mapActionToProps = (dispatch) => ({
addNum(num) {
dispatch(addNum(num))
}
})
export default connect(mapStateToProps, mapActionToProps)(App)
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbafjg
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13