切记:class内不要用箭头函数,因为箭头函数的作用就是绑定this指针,如果绑定了this指针会导致proxy无法监听到数据变更。
第一步
第二步
实现解析: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的其他各个功能。