目标
实现Provider
组件和connect
函数。
开始
新建react-redux
文件夹和入口文件index.js
,导出对应组件和方法:
// react-redux/index.js
export {
Provider,
connect
}
context
react-redux
基于 React.Context
实现,所以首先创建context:
// context.js
import React from "react";
export default React.createContext();
Provider
//Provider.js
import React,{Component} from "react";
import ReduxContext from "./context";
export default class Provider extends Component {
render(){
return (
<ReduxContext.Provider value={{ store: this.props.store }}>
{this.props.children}
</ReduxContext.Provider>
)
}
}
Provider.js
拿到父组件传过来的store,并把它交给Provider,方便向下传递,接着渲染子组件。
connect
connect返回一个函数并且接收渲染的的组件:
//connect.js
export default function connect(mapStateToProps, mapDispatchToProps){
return (WrapperComponent)=>{}
}
返回的函数最终是经过执行后再抛出,所以返回的应该是一个类组件
或者一个函数组件
,这里用到类组件
会比较合适,因为还要对订阅的更新视图函数进行销毁操作,然后store可以通过向下传递的context
拿到:
//connect.js
import ReduxContext from './context'
import React, { Component } from 'react'
export default function connect(mapStateToProps, mapDispatchToProps) {
return (WrapperComponent)=> {
return class extends Component {
static contextType = ReduxContext
constructor(props, context) {
super(props);
// 通过mapStateToProps 返回包装后的state,这里可方便用户拿到想要的state,同时优化渲染的组件
this.state = mapStateToProps(context.store.getState())
}
componentDidMount() {
// 订阅更新视图
this.unSubscribe = this.context.store.subscribe(() => {
this.setState(mapStateToProps(this.context.store.getState()))
})
}
componentWillUnmount() {
// 注销订阅
this.unSubscribe()
}
}
}
}
render
里面通过传参的方式将store里面的值和处理过的action传给子组件:
//connect.js
...
render() {
// 处理绑定的action
let actions = redux.bindActionCreator(mapDispatchToProps,this.context.store.dispatch);
return <WrapperComponent {...this.state} {...actions} />
}
...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。