美文网首页
Taro中使用mixin

Taro中使用mixin

作者: kofzx | 来源:发表于2020-01-03 17:26 被阅读0次

    最近开始搞搞Taro,发现Taro当中好像没有mixin耶o(╥﹏╥)o,于是我开始去查阅文档,发现react在疯狂地diss mixin,原谅我才疏学浅,mixin在我看来只是命名冲突会有点烦,但尽量避免的话用起来还是很爽的。(可能没有经历过大项目吧)
    那么,对于我们小项目就是想用mixin咋办?react就疯狂地给我们安利高阶组件(hoc)了。我们照着官网写个示例:

    // withTest.js
    import { Component } from '@tarojs/taro'
    
    function withTest(Comp) {
        return class extends Component {
            render() {
                return <Comp />
            }
        }
    }
    
    // A.js
    import withTest from '../withTest'
    
    @withTest
    class A extends Component {}
    export default A
    

    在react环境里用hoc完全没问题,但是Taro环境就不一样了,它直接不调用hoc里返回class的render方法了,甚至还给你报了个错!


    报错1.png
    15764c13f5e2e4125dd583eab0b35360.jpg

    解决这个报错呢,可以这样:

    function withTest(Comp) {
        return class extends Comp {
            render() {
                return <Comp />
            }
        }
    }
    

    虽说这样解决了报错,但render方法它始终不肯执行,其他的生命周期诸如componentWillMount等会执行。于是我去看了隔壁redux的connect源码,毕竟人家可以注入props到组件,人家也是高阶组件,要向它学习:

    // 摘要代码
    return class Connect extends Component {
          constructor (props, isPage) {
            super(Object.assign(...arguments, mergeObjects(mapStateToProps(store.getState(), props), initMapDispatch)), isPage)
            Object.keys(initMapDispatch).forEach(key => {
              this[`__event_${key}`] = initMapDispatch[key]
            })
          }
    
          _constructor () {
            if (!this.$scope) {
              if (super._constructor) {
                super._constructor(this.props)
              }
              return
            }
            const store = getStore()
            Object.assign(this.props, mergeObjects(mapStateToProps(store.getState(), this.props), initMapDispatch))
            unSubscribe = store.subscribe(stateListener.bind(this))
            if (super._constructor) {
              super._constructor(this.props)
            }
          }
    
          componentWillUnmount () {
            if (super.componentWillUnmount) {
              super.componentWillUnmount()
            }
            if (unSubscribe) {
              unSubscribe()
            }
            unSubscribe = null
          }
        }
    

    什么嘛,原来connect根本就没有调render嘛,那么我们也不要去纠结于render方法了,干就完了。

    披着高阶组件的外衣,mixin来了!

    用法一(直接在类里写方法)
    // withTest.js
    function withTest(Comp) {
        return class extends Comp {
            a() { console.log('a'); }
            b() {
                this.a();
                console.log('b');
            }
        }
    }
    // A.js
    @withTest
    class A extends Component {
        componentWillMount() {
            this.b();  
            // a
            // b
        }
    }
    
    用法二(state)
    // 借助一个深拷贝对象的方法
    const mergeObjects = function(obj1, obj2) {
        const result = Object.assign({}, obj1);
        if (isObject(obj1) && isObject(obj2)) {
            for (const p in obj2) {
                if (isObject(obj1[p]) && isObject(obj2[p])) {
                    result[p] = mergeObjects(obj1[p], obj2[p]);
                } else {
                    result[p] = obj2[p];
                }
            }
        }
        return result;
    };
    // withTest.js
    function withTest(Comp) {
        return class extends Comp {
            constructor(props) {
                super(props);
                this.state = mergeObjects(this.state, { a: 1 });
            }
            changeA(fn) {
                this.setState({ a: 2 }, () => fn && fn());
            }
        }
    }
    // A.js
    @withTest
    class A extends Component {
        constructor(props) {
                super(props);
                this.state = { a: 10, b: 2 };
         }
         componentWillMount() {
             this.changeA(() => console.log(this.state));
             // a: 2
             // b: 2
         }
    }
    

    相关文章

      网友评论

          本文标题:Taro中使用mixin

          本文链接:https://www.haomeiwen.com/subject/bhwzoctx.html