Match-id-36a3aeae070795ceee07c5bd46be79ae9649ebc2

This commit is contained in:
* 2021-12-25 15:07:38 +08:00 committed by *
parent 795a0192a4
commit 6d5f3c6888
9 changed files with 48 additions and 43 deletions

View File

@ -1,11 +1,12 @@
/**
* Component的api setState和forceUpdate在实例生成阶段实现
*/
class Component {
props;
context;
class Component<P,S,C> {
props: P;
context: C;
state: S;
constructor(props, context) {
constructor(props: P, context: C) {
this.props = props;
this.context = context;
}
@ -16,8 +17,8 @@ Component.prototype.isReactComponent = true;
/**
* PureComponent
*/
class PureComponent extends Component {
constructor(props, context) {
class PureComponent<P, S, C> extends Component<P, S, C> {
constructor(props: P, context: C) {
super(props, context);
}
}

View File

@ -15,7 +15,7 @@ type LazyContent<T> = {
};
export type LazyComponent<T, P> = {
vtype: Symbol | number,
vtype: number,
_content: P,
_load: (content: P) => T,
};

View File

@ -3,7 +3,8 @@ import type {Hook} from './HookType';
let processingVNode: VNode = null;
let activatedHook: Hook<any, any> | null = null;
// lastTimeHook是上一次执行func时产生的hooks中与currentHook对应的hook
let lastTimeHook: Hook<any, any> | null = null;
// 当前hook函数对应的hook对象
let currentHook: Hook<any, any> | null = null;
@ -16,12 +17,12 @@ export function setProcessingVNode(vNode: VNode) {
processingVNode = vNode;
}
export function getActivatedHook() {
return activatedHook;
export function getLastTimeHook() {
return lastTimeHook;
}
export function setActivatedHook(hook: Hook<any, any>) {
activatedHook = hook;
export function setLastTimeHook(hook: Hook<any, any>) {
lastTimeHook = hook;
}
export function setCurrentHook(hook: Hook<any, any>) {
@ -47,24 +48,32 @@ export function createHook(state: any = null): Hook<any, any> {
return currentHook;
}
export function getNextHook(hook: Hook<any, any>, vNode: VNode) {
return vNode.hooks[hook.hIndex + 1] || null;
export function getNextHook(hook: Hook<any, any>, hooks: Array<Hook<any, any>>) {
return hooks[hook.hIndex + 1] || null;
}
// 获取当前hook函数对应的hook对象。
// processing中的hook和activated中的hook需要同时往前走
// 原因1.比对hook的数量有没有变化非必要2.从activated中的hook获取removeEffect
// processing中的hook和上一次执行中的hook需要同时往前走
// 原因1.比对hook的数量有没有变化非必要2.从上一次执行中的hook获取removeEffect
export function getCurrentHook(): Hook<any, any> {
currentHook = currentHook !== null ? getNextHook(currentHook, processingVNode) : (processingVNode.hooks[0] || null);
const activated = processingVNode.twins;
activatedHook = activatedHook !== null ? getNextHook(activatedHook, activated) : ((activated && activated.hooks[0]) || null);
currentHook = currentHook !== null ? getNextHook(currentHook, processingVNode.hooks) : (processingVNode.hooks[0] || null);
if (lastTimeHook !== null) {
lastTimeHook = getNextHook(lastTimeHook, processingVNode.oldHooks);
} else {
if (processingVNode.oldHooks && processingVNode.oldHooks.length) {
lastTimeHook = processingVNode.oldHooks[0];
} else {
lastTimeHook = null;
}
}
if (currentHook === null) {
if (activatedHook === null) {
if (lastTimeHook === null) {
throw Error('Hooks are more than expected, please check whether the hook is written in the condition.');
}
createHook(activatedHook.state);
createHook(lastTimeHook.state);
}
return currentHook;

View File

@ -9,9 +9,9 @@ const {
import {getNewContext} from '../components/context/Context';
import {
getActivatedHook,
getLastTimeHook,
getProcessingVNode,
setActivatedHook,
setLastTimeHook,
setProcessingVNode,
setCurrentHook, getNextHook
} from './BaseHook';
@ -24,7 +24,6 @@ export function exeFunctionHook(
funcComp: (props: Object, arg: Object) => any,
props: Object,
arg: Object,
activated: VNode | null,
processing: VNode,
): any {
// 重置全局变量
@ -35,11 +34,12 @@ export function exeFunctionHook(
setProcessingVNode(processing);
processing.oldHooks = processing.hooks;
processing.hooks = [];
processing.effectList = [];
// 设置hook阶段
if (activated === null || !activated.hooks.length) {
if (processing.isCreated || !processing.oldHooks.length) {
setHookStage(HookStage.Init);
} else {
setHookStage(HookStage.Update);
@ -51,9 +51,9 @@ export function exeFunctionHook(
setHookStage(null);
// 判断hook是否写在了if条件中如果在if中会出现数量不对等的情况
const activatedHook = getActivatedHook();
if (activatedHook !== null) {
if (getNextHook(getActivatedHook(), activated) !== null) {
const lastTimeHook = getLastTimeHook();
if (lastTimeHook !== null) {
if (getNextHook(getLastTimeHook(), processing.oldHooks) !== null) {
throw Error('Hooks are less than expected, please check whether the hook is written in the condition.');
}
}
@ -67,7 +67,7 @@ export function exeFunctionHook(
function resetGlobalVariable() {
setHookStage(null);
setProcessingVNode(null);
setActivatedHook(null);
setLastTimeHook(null);
setCurrentHook(null);
}

View File

@ -1,5 +1,4 @@
import {EffectConstant} from './EffectConstant';
import {VNode} from '../Types';
export interface Hook<S, A> {
state: Reducer<S, A> | Effect | Memo<S> | CallBack<S> | Ref<S>;

View File

@ -1,7 +1,7 @@
import {
createHook,
getCurrentHook,
getActivatedHook,
getLastTimeHook,
getProcessingVNode, throwNotInFuncError
} from './BaseHook';
import {FlagUtils} from '../vnode/VNodeFlags';
@ -38,10 +38,10 @@ function useEffect(
}
export function useEffectForInit(effectFunc, deps, effectType): void {
const hook = createHook();
const nextDeps = deps !== undefined ? deps : null;
FlagUtils.markUpdate(getProcessingVNode());
const hook = createHook();
const nextDeps = deps !== undefined ? deps : null;
// 初始阶段设置DepsChange标记位; 构造EffectList数组并赋值给state
hook.state = createEffect(effectFunc, undefined, nextDeps, EffectConstant.DepsChange | effectType);
}
@ -51,13 +51,13 @@ export function useEffectForUpdate(effectFunc, deps, effectType): void {
const nextDeps = deps !== undefined ? deps : null;
let removeFunc;
if (getActivatedHook() !== null) {
const effect = getActivatedHook().state as Effect;
// removeEffect是通过执行effect返回的所以需要在activated中获取
if (getLastTimeHook() !== null) {
const effect = getLastTimeHook().state as Effect;
// removeEffect是通过执行effect返回的所以需要在上一次hook中获取
removeFunc = effect.removeEffect;
const lastDeps = effect.dependencies;
// 判断dependencies是否相同不同就不设置DepsChange标记位
// 判断dependencies是否相同同相同不需要设置DepsChange标记位
if (nextDeps !== null && isArrayEqual(nextDeps, lastDeps)) {
hook.state = createEffect(effectFunc, removeFunc, nextDeps, effectType);
return;

View File

@ -54,10 +54,9 @@ function insertUpdate<S, A>(action: A, hook: Hook<S, A>): Update<S, A> {
// setState, setReducer触发函数
export function TriggerAction<S, A, T>(vNode: VNode, hook: Hook<S, A>, action: A) {
const newUpdate = insertUpdate(action, hook);
const twins = vNode.twins;
// 判断是否需要刷新
if (!vNode.shouldUpdate && (twins === null || !twins.shouldUpdate)) {
if (!vNode.shouldUpdate) {
const reducerObj = hook.state as Reducer<S, A>;
const { stateValue, reducer } = reducerObj;

View File

@ -80,7 +80,7 @@ function callTasks(initialTime) {
task.expirationTime > currentTime &&
isOverTime()
) {
// 没到deadline
// 任务的过期时间大于当前时间(此任务的过期时间)且超过了deadline
break;
}

View File

@ -1,3 +0,0 @@
{
"horizon-test-path": "../horizon-test"
}