hello,大家好今天让我们一起实现下自己react-redux吧!上一篇我们分享了redux,不懂的可以直接查看额,本篇文章适合有一定基础的react开发人员,用到了react Context api 不懂的可以先查看下,文本较长,建议收藏,废话不说,直接上干货!!!
一、从入口文件开始
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from '@/pages/home'
// 引入我们自己的provider
import { Provider } from './myReactRedux/provider'
// 引入上期的store
import store from '@/store/store'
ReactDOM.render(
<React.StrictMode>
<Provider store={ store }>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
二、创建myReactRedux文件夹
import React, { Component } from 'react'
// provider比较简单就是一个高阶组件
class Provider extends Component {
render() {
return (
<div>
{this.props.children}
</div>
)
}
}
export { Provider }
这里我们就可以页面内容了,那么我们的store数据怎么传递呢?
三、创建createContext.js内容
import React from 'react'
// react context
const ValueContext = React.createContext();
export default ValueContext
此时我们回过头来给provider.js绑定store
import React, { Component } from 'react'
//引入
import ValueContext from './createContext'
class Provider extends Component {
render() {
return (
// context属性传递,这里去订阅了store的数据传递给了组件
<ValueContext.Provider value={ this.props.store}>
{this.props.children}
</ValueContext.Provider>
)
}
}
export { Provider }
此时我们就可以在控制台打印出我们this.props看下了,是不是很简答哇!
四、创建connect.js内容
import React, { Component } from 'react'
// 接收参数,组件,直接将组件返回
export const connect = (
mapStateToProps,
mapDispatchToProps
) => WrappedComponent => {
return class extends Component {
render() {
return <WrappedComponent />;
}
}
}
五、connect函数订阅数据传递给组件
import React, { Component } from 'react'
import ValueContext from './createContext'
// 接收参数和组件,直接将组件返回
export const connect = (
mapStateToProps,
mapDispatchToProps
) => WrappedComponent => {
return class extends Component {
// 挂载contextType属性
static contextType = ValueContext
render() {
return <WrappedComponent />;
}
}
}
此时context就被我们挂载到了this上
六、mapStateToProps
import React, { Component } from 'react'
import ValueContext from './createContext'
// 接收参数和组件,直接将组件返回
export const connect = (
mapStateToProps,
mapDispatchToProps
) => WrappedComponent => {
return class extends Component {
// 挂载contextType属性
static contextType = ValueContext
//为了修改props让组件更新变化,需要调用setState,所以这里重新创建下
constructor(props) {
super(props);
this.state = {
props: {}
};
}
componentDidMount() {
this.update();
//我们在mount阶段去获取一下context中的值
const { subscribe, getState } = this.context
subscribe(() => {
this.update();
})
}
update = () => {
const { getState, dispatch } = this.context;
//查看一下传递过来的类型
// console.log(mapStateToProps, mapDispatchToProps);
//直接返回state的值
const stateProps = mapStateToProps(getState())
let dispatchProps;
this.setState({
props: {
...stateProps,
...dispatchProps
}
});
}
render() {
return <WrappedComponent {...this.props} {...this.state.props}/>;
}
}
}
七、mapDispatchToProps
function bindActionCreator(creator, dispatch) {
return (...args) => dispatch(creator(...args));
}
// 循环绑定包裹dispatch
function bindActionCreators(creators,dispatch) {
const obj = {};
for (const key in creators) {
obj[key] = bindActionCreator(creators[key],dispatch);
}
return obj;
}
export { bindActionCreators }
然后就可以实现我们的mapDispatchToPropsle
import React, { Component } from 'react'
import ValueContext from './createContext'
import { bindActionCreators } from './bindActionCreators'
// 接收参数和组件,直接将组件返回
export const connect = (
mapStateToProps,
mapDispatchToProps
) => WrappedComponent => {
return class extends Component {
// 挂载contextType属性
static contextType = ValueContext
constructor(props) {
super(props);
this.state = {
props: {}
};
}
componentDidMount() {
this.update();
//我们在mount阶段去获取一下context中的值
//看下context中有什么吧
// console.log(this.context)
const { subscribe, getState } = this.context
//这里已经可以看到我们的值了
// console.log(getState())
subscribe(() => {
this.update();
})
}
update = () => {
const { getState, dispatch } = this.context;
//查看一下传递过来的类型
// console.log(mapStateToProps, mapDispatchToProps);
//直接返回state的值
const stateProps = mapStateToProps(getState())
let dispatchProps;
if (typeof mapDispatchToProps === "object") {
// 办理object,分别绑定dispath方法
dispatchProps = bindActionCreators(mapDispatchToProps,dispatch);
} else if (typeof mapDispatchToProps === "function") {
// 绑定dispath方法
dispatchProps = mapDispatchToProps(dispatch, this.props);
} else {
// 直接绑定
dispatchProps = { dispatch };
}
this.setState({
props: {
...stateProps,
...dispatchProps
}
});
}
render() {
return <WrappedComponent {...this.props} {...this.state.props}/>;
}
}
}
ok,你学会了吗?快来试试新技能吧!
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!