context了解一下
- 上下文环境
- 使用了就要类型校验
- 只能被子组件访问到
父组件中要对将要传入子组件的context进行类型校验并设置context对象
class App extends Component {
constructor(props){
super(props);
this.state = {
user: 'binyellow'
}
}
static childContextTypes = {
user: propTypes.string
}
getChildContext(){
return this.state
}
render(){
return (
<div>
App
<GrandChild></GrandChild>
</div>
)
}
}
在使用context的子组件中必须校验
class GrandChild extends Component{
static contextTypes = {
user: propTypes.string
}
render(){
console.log(this.context);
return(
<div>
GrandChildName: {this.context.user}
</div>
)
}
}
高阶函数了解一下
- connect函数形如:
connect(mapStateToProps,mapDispatchToProps)(APP)
- 实质上是高阶函数中返回了一个高阶组件
- 怎么实现
export function connect(mapStateToProps,mapDispatchToProps){
return function(WrappedComponent){
return class ConnectComponent extends Component{
...
}
}
}
- 箭头函数实现
export const connect = (mapStateToProps,mapDispatchToProps)=>(WrappedComponent)=>{
return class ConnectComponent extends Component{
...
}
}
connect是什么:connect其实就是给传入的组件包裹上context的属性,来拿到全局的属性store
正题:connect如何实现
export const connect = (mapStateToProps=state=>state,mapDispatchToProps={})=>(WrappedComponent)=>{
return class ConnectComponent extends Component{
static contextTypes = {
store: propTypes.object
}
constructor(props,context){
super(props,context)
this.state = {
props:{}
}
}
componentDidMount(){
//每次dispatch都会触发subscribe,利用此来更新stateProps
const {store} = this.context;
store.subscribe(()=>this.update())
this.update()
}
update(){
const {store} = this.context;
console.log(store);
// 这里面来把state分发出去
const stateProps = mapStateToProps(store.getState());
// 这里把action都包一层dispatch
const actionProps = bindActionCreators(mapDispatchToProps,store.dispatch) // bindActionCreators详见redux
this.setState({
props: {
...this.state.props,
...stateProps,
...actionProps
}
})
}
render(){
return (
// 从context中获取的state和用dispatch包装后的action传给组件WrappedComponent
<WrappedComponent {...this.state.props}></WrappedComponent>
)
}
}
}