最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 深入学习react(二) 写个自己的react-redux

    正文概述 掘金(ぃ秋水无痕)   2021-04-27   504

    深入学习react(二) 写个自己的react-redux

    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,你学会了吗?快来试试新技能吧!


    起源地下载网 » 深入学习react(二) 写个自己的react-redux

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元