最简易的实现mobx部分功能

88 阅读1分钟

切记:class内不要用箭头函数,因为箭头函数的作用就是绑定this指针,如果绑定了this指针会导致proxy无法监听到数据变更。

第一步

image.png

第二步

image.png

实现解析:createContext创建全局props, 然后通过useContext去使用对应的context,所以再Inject函数内去获取到context的内容,并通过proxy去监听context的内容变动,因为匿名声明的对象对于内存来说每次都需要重新创建引用地址,所以setState({})会强制刷新页面。以此来实现context内容变动刷新页面数据的效果。


实现的代码

import React,{createContext,useState} from 'react';

//1. 关于 createContext
const LstateContext = createContext({c:200}) 
export const Provider = function (props){
  const {store,children} = props
  return React.createElement(LstateContext.Provider,{value:store},children)
}

export const Inject = function (storeName){
  return function (Com){
    var Injector = React.forwardRef((props,ref)=>{
      const [,setState] = useState({})
      var newProps = _extends({}, props);
      var context = React.useContext(LstateContext);
      const injectStore = context[storeName]
      const proxyObj = new Proxy(injectStore||{},{
        set: (target, property, value, reciver) => {
          if(target[property] !== value){
            setState({})
          }
         return Reflect.set(target, property, value) //todo 这是赋值操作
        },
      
        get: (target, property, reciver) => {
          return Reflect.get(target, property)
        }
      })
      Object.assign(newProps, {[storeName]: proxyObj});
      if (ref) {
        newProps.ref = ref;
      }

      return React.createElement(Com,newProps)
    })
    return Injector
  }
}
function _extends() {
  _extends = Object.assign || function (target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i];

      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }

    return target;
  };

  return _extends.apply(this, arguments);
}

再复杂的的源码都从最简单功能开始实现吧,后续的只是在去扩展他的兼容性和功能的复杂度。希望看完这个最简单的mobx实现的源码后能逐步去实现mobx的其他各个功能。