实现一个miniHOOK

    let isMount = true;
    let fiber = {
        stateNode: App,
        memoizedState: null
    };
    let workInProgressHook = null;
    function schedule() {
        workInProgressHook = fiber.memoizedState;
        const app = fiber.stateNode();
        isMount = false;
        return app;
    }
    
    function dispatchAction(queue, action) {
        let update = {
            action,
            next: null
        };
        
        if (queue.pending === null) {
            update.next = update;
        } else {
            update.next = queue.pending.next;
            queue.pending.next = update;
        }
        
        queue.pending = update;
        schedule();
    }
    
    function useState(initialState) {
        let hook;
        
        if (isMount) {
            hook = {
                queue: {
                    pending: null
                },
                next: null,
                memoizedState: initialState
            };
            
            if (!fiber.memoizedState) {
                fiber.memoizedState = hook;
            } else {
                workInProgressHook.next = hook;
            }
            
            workInProgressHook = hook;
        } else {
            hook = workInProgressHook;
            workInProgressHook = workInProgressHook.next;
        }
        
        let baseState = hook.memoizedState;
        
        if (hook.queue.pending) {
            let firstUpdate = hook.queue.pending.next;
            
            do {
                const action = firstUpdate.action;
                baseState = action(baseState);
                firstUpdate = firstUpdate.next;
            } while(firstUpdate !== hook.queue.pending);
            
            hook.queue.pending = null;
        }
        
        hook.memoizedState = baseState;
        
        return [baseState, dispatchAction.bind(null, hook.queue)];
    }
    
    function App() {
        let [num, updateNum] = useState(0);
        
        console.log(`${isMount ? 'mount' : 'update'}: ${num}`);
        
        return {
            click() {
                updateNum(num => {
                    return num + 1;
                });
            }
        }
    }
    window.app = schedule();

你可能感兴趣的:(实现一个miniHOOK)