Lemonreds / snippets

code snippets.
https://github.com/Lemonreds/snippets/issues
2 stars 0 forks source link

[2020-08-31]: preact中hook的实现代码片段 #14

Open Lemonreds opened 4 years ago

Lemonreds commented 4 years ago

preact中hook的实现代码片段

preact 是一个很棒的库,通过其hook的实现代码,可以让你对hook有一种豁达开朗的感觉,这里收集了下代码,方便及时查阅。

getHookState

function getHookState(index, type) {
    if (options._hook) {
        options._hook(currentComponent, index, currentHook || type);
    }
    currentHook = 0;
    const hooks =
        currentComponent.__hooks ||
        (currentComponent.__hooks = {
            _list: [],
            _pendingEffects: []
        });

    if (index >= hooks._list.length) {
        hooks._list.push({});
    }
    return hooks._list[index];
}

useReducer

 function useReducer(reducer, initialState, init) {
    const hookState = getHookState(currentIndex++, 2);
    hookState._reducer = reducer;
    if (!hookState._component) {
        hookState._component = currentComponent;
        hookState._value = [
            !init ? invokeOrReturn(undefined, initialState) : init(initialState),
            action => {
                const nextValue = hookState._reducer(hookState._value[0], action);
                if (hookState._value[0] !== nextValue) {
                    hookState._value = [nextValue, hookState._value[1]];
                    hookState._component.setState({});
                }
            }
        ];
    }
    return hookState._value;
}

useState

 function useState(initialState) {
    currentHook = 1;
    return useReducer(invokeOrReturn, initialState);
}

useEffect

 function useEffect(callback, args) {
    const state = getHookState(currentIndex++, 3);
    if (!options._skipEffects && argsChanged(state._args, args)) {
        state._value = callback;
        state._args = args;
        currentComponent.__hooks._pendingEffects.push(state);
    }
}

useMemo

 function useMemo(factory, args) {  
    const state = getHookState(currentIndex++, 7);
    if (argsChanged(state._args, args)) {
        state._args = args;
        state._factory = factory;
        return (state._value = factory());
    }
    return state._value;
}

useRef

function useRef(initialValue) {
    currentHook = 5;
    return useMemo(() => ({ current: initialValue }), []);
}

useCallback

function useCallback(callback, args) {
    currentHook = 8;
    return useMemo(() => callback, args);
}
Lemonreds commented 4 years ago

useEffect相关