概述
众所周知,react-redux只是帮忙管理一下redux的store。
react-redux 有两个重要组成:Provider 和 connect。
-
Provider 接收store作为props,然后通过context往下传递,以至任何组件都能获取store。
-
connect 作为高阶组件对原有组件进行强化,接收两个参数,mapStateToProps 和 mapDispatchToProps。
mapStateToProps 自动接收state,mapDispatchToProps 自动接收dispatch。
前者是一个方法(返回一个对象),后者是一个对象(里面包含dispatch方法)。
调用connect之后,react-redux就会帮助我们进行store的操作。把我们写的属性,方法,还有父组件的传值传入我们要强化的组件的props。
在redux里面,我们也可以用store.getState( ) , store.dispatch( )直接进行store操作。
照着这个逻辑,就可以仿写一下connect了。
代码
import store from '../../store';
class Com extends Component {
render() {
return (
<div>
<button onClick={this.props.minus}>-</button>
</div>
)
}
}
function connectFun(callback,obj){
var value = callback() //执行传入的mapStateToProps得到值
return (MyComponent)=>{ //将传入的组件作为参数调用
return (props)=>{ //获取父组件传入的值
return <div>
{/* 将父组件传入的和传入的两个参数一起传给要强化的组件 */}
<MyComponent {...value} {...obj} {...props} ></MyComponent>
</div>
}
}
}
const mapStateToProps = () =>{
let store_state = store.getState()
return {
...store_state
}
}
const mapDispatchToProps = {
minus:()=>{
store.dispatch({
type:'minus_action'
})
}
}
export default connectFun( mapStateToProps , mapDispatchToProps )(Com)
这里的第一步直接引入了store进行操作。
Provider 为了每个组件都能访问store,通过context传递,那我们能不能在context里面直接取得store就不用引入了呢?
但是我后面怎么找都找不到,看看它的源码:
import { Component, Children } from 'react'
import PropTypes from 'prop-types'
import storeShape from '../utils/storeShape'
import warning from '../utils/warning'
export default class Provider extends Component {
getChildContext() {
return { store: this.store }
}
constructor(props, context) {
super(props, context)
this.store = props.store
}
render() {
return Children.only(this.props.children)
}
}
getChildContext 之后就不知道去哪了。
既然取不到store,那把Provider一块删了吧。
最后可以把这个 connectFun 封装一下,把store作为一个参数,这样就不用每次引入了,只需引入这个封装的方法,和原始引入的 import { connect } from 'react-redux' 一样。
感想
这个connect高阶组件好像proxy代理,可以对另一个组件进行数据的拦截,中途插入一些操作。