|
@@ -24,7 +24,7 @@ let currentInstance: ComponentInstance | null = null
|
|
|
let isMounting: boolean = false
|
|
let isMounting: boolean = false
|
|
|
let callIndex: number = 0
|
|
let callIndex: number = 0
|
|
|
|
|
|
|
|
-const hooksState = new WeakMap<ComponentInstance, HookState>()
|
|
|
|
|
|
|
+const hooksStateMap = new WeakMap<ComponentInstance, HookState>()
|
|
|
|
|
|
|
|
export function setCurrentInstance(instance: ComponentInstance) {
|
|
export function setCurrentInstance(instance: ComponentInstance) {
|
|
|
currentInstance = instance
|
|
currentInstance = instance
|
|
@@ -36,6 +36,18 @@ export function unsetCurrentInstance() {
|
|
|
currentInstance = null
|
|
currentInstance = null
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function getHookStateForInstance(instance: ComponentInstance): HookState {
|
|
|
|
|
+ let hookState = hooksStateMap.get(instance)
|
|
|
|
|
+ if (!hookState) {
|
|
|
|
|
+ hookState = {
|
|
|
|
|
+ state: observable({}),
|
|
|
|
|
+ effects: []
|
|
|
|
|
+ }
|
|
|
|
|
+ hooksStateMap.set(instance, hookState)
|
|
|
|
|
+ }
|
|
|
|
|
+ return hookState
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
export function useState<T>(initial: T): [T, (newValue: T) => void] {
|
|
export function useState<T>(initial: T): [T, (newValue: T) => void] {
|
|
|
if (!currentInstance) {
|
|
if (!currentInstance) {
|
|
|
throw new Error(
|
|
throw new Error(
|
|
@@ -43,7 +55,7 @@ export function useState<T>(initial: T): [T, (newValue: T) => void] {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
const id = ++callIndex
|
|
const id = ++callIndex
|
|
|
- const { state } = hooksState.get(currentInstance) as HookState
|
|
|
|
|
|
|
+ const { state } = getHookStateForInstance(currentInstance)
|
|
|
const set = (newValue: any) => {
|
|
const set = (newValue: any) => {
|
|
|
state[id] = newValue
|
|
state[id] = newValue
|
|
|
}
|
|
}
|
|
@@ -76,7 +88,7 @@ export function useEffect(rawEffect: Effect, deps?: any[]) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
effect.current = rawEffect
|
|
effect.current = rawEffect
|
|
|
- ;(hooksState.get(currentInstance) as HookState).effects[id] = {
|
|
|
|
|
|
|
+ getHookStateForInstance(currentInstance).effects[id] = {
|
|
|
effect,
|
|
effect,
|
|
|
cleanup,
|
|
cleanup,
|
|
|
deps
|
|
deps
|
|
@@ -86,7 +98,7 @@ export function useEffect(rawEffect: Effect, deps?: any[]) {
|
|
|
injectEffect(currentInstance, 'unmounted', cleanup)
|
|
injectEffect(currentInstance, 'unmounted', cleanup)
|
|
|
injectEffect(currentInstance, 'updated', effect)
|
|
injectEffect(currentInstance, 'updated', effect)
|
|
|
} else {
|
|
} else {
|
|
|
- const record = (hooksState.get(currentInstance) as HookState).effects[id]
|
|
|
|
|
|
|
+ const record = getHookStateForInstance(currentInstance).effects[id]
|
|
|
const { effect, cleanup, deps: prevDeps = [] } = record
|
|
const { effect, cleanup, deps: prevDeps = [] } = record
|
|
|
record.deps = deps
|
|
record.deps = deps
|
|
|
if (!deps || deps.some((d, i) => d !== prevDeps[i])) {
|
|
if (!deps || deps.some((d, i) => d !== prevDeps[i])) {
|
|
@@ -110,12 +122,6 @@ function injectEffect(
|
|
|
export function withHooks(render: FunctionalComponent): new () => Component {
|
|
export function withHooks(render: FunctionalComponent): new () => Component {
|
|
|
return class ComponentWithHooks extends Component {
|
|
return class ComponentWithHooks extends Component {
|
|
|
static displayName = render.name
|
|
static displayName = render.name
|
|
|
- created() {
|
|
|
|
|
- hooksState.set((this as any)._self, {
|
|
|
|
|
- state: observable({}),
|
|
|
|
|
- effects: []
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
render(props: Data, slots: Slots, attrs: Data, parentVNode: VNode) {
|
|
render(props: Data, slots: Slots, attrs: Data, parentVNode: VNode) {
|
|
|
setCurrentInstance((this as any)._self)
|
|
setCurrentInstance((this as any)._self)
|
|
|
const ret = render(props, slots, attrs, parentVNode)
|
|
const ret = render(props, slots, attrs, parentVNode)
|