Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 6x 6x 6x 6x 6x 6x 6x 11x 4x 7x 7x 4x 4x 6x 4x 4x 4x 8x 8x 8x 8x 3x 9x 7x 7x 4x 4x 4x 4x 3x 6x 2x 2x 2x 6x | /*
* @Author: lijianzhang
* @Date: 2018-03-31 21:40:26
* @Last Modified by: lijianzhang
* @Last Modified time: 2018-08-29 23:50:29
* @flow
*/
import * as React from 'react';
import { SFC } from 'react';
import Observer from './observer';
import { OBSERVER_COMPONENT_KEY } from './constant';
const baseRenderKey = Symbol('baseRender');
const connectKey = Symbol('connect');
const $componentWillMount = Symbol('componentWillMount');
type IReactComponent<P = any> =
| React.StatelessComponent<P>
| React.ComponentClass<P>
| React.ClassicComponentClass<P>;
E
function reactiveRender(this: React.Component) {
return this[OBSERVER_COMPONENT_KEY].collectDep(this[baseRenderKey]);
}
function initRender(this: React.Component) {
this[OBSERVER_COMPONENT_KEY] = new Observer(() => {
if (this[$componentWillMount]) {
this.forceUpdate();
}
}, `${this.constructor.name}.render()`);
this.render = reactiveRender;
return reactiveRender.call(this);
}
const reactiveMixin = {
componentWillMount(this: React.Component) {
this[$componentWillMount] = true;
this[baseRenderKey] = this.render.bind(this);
this.render = initRender;
E},
componentWillUnmount(this: React.Component) {
this[OBSERVER_COMPONENT_KEY].unSubscribe();
this[OBSERVER_COMPONENT_KEY] = null;
},
};
function patch(target, funcName, runMixinFirst = false) {
const base = target[funcName];
const mixinFunc = reactiveMixin[funcName];
if (!base) {
target[funcName] = mixinFunc;
} else {
target[funcName] =
runMixinFirst === true ?
function funcName(this: React.Component, ...args) {
mixinFunc.apply(this, args);
base.apply(this, args);
} :
function funcName(this: React.Component, ...args) {
base.apply(this, args);
mixinFunc.apply(this, args);
};
}
}
function createObserverComponent(component: IReactComponent) {
return class extends React.Component {
I static displayName = component.displayName || component.name;
static propTypes = component.propTypes;
static contextTypes = component.contextTypes;
static defaultProps = component.defaultProps;
render() {
return component.call(this, this.props, this.context);
}
};
}
export default function ReactObserver<T extends IReactComponent>(target: T | SFC): T {
Iif (target[connectKey]) return (target as T);
if ( typeof target === "function" && (target.prototype && target.prototype.render) ) {
target[connectKey] = true;
patch(target.prototype, 'componentWillMount', true);
patch(target.prototype, 'componentWillUnmount');
return (target as T);
}
return ReactObserver(createObserverComponent(target as IReactComponent)) as any;
}
interface Props {
children?: SFC | React.Factory<any> ;
render?: SFC;
}
export function ObserverComponent(target: Props) {
let Component = target.children || target.render;
if (!Component) return null;
return React.createElement(ReactObserver(Component));
}
|