Created
July 1, 2019 18:48
-
-
Save ProdigySim/21663d3fd89562e9d55c8cce1772c405 to your computer and use it in GitHub Desktop.
Here's my naiive assumption of how hooks are implemented.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| let global_currentHooks: object[] | null = null; | |
| let global_currentHookIndex: number | null = null; | |
| function getNextHook() { | |
| return global_currentHooks![global_currentHookIndex!]; | |
| } | |
| const state = new Map(); | |
| function doRender(componentFn: () => string) { | |
| // Setup the "global" hooks array, for our component to use. | |
| global_currentHooks = state.get(componentFn) || []; | |
| global_currentHookIndex = 0; | |
| // Run the component's render function. It will call various hooks, | |
| // which will operate on the global "currentHooks" array. | |
| const res = componentFn(); | |
| // Save the state of these hooks back to our store. | |
| state.set(componentFn, global_currentHooks); | |
| global_currentHooks = null; | |
| global_currentHookIndex = null; | |
| return res; | |
| } | |
| type StateHookObject<T> = { | |
| value: T, | |
| updater: (v: T) => void, | |
| }; | |
| function createStateHook<T>(initialValue: T) { | |
| const obj = { | |
| value: initialValue, | |
| updater: (v: T) => { obj.value = v; }, | |
| } | |
| global_currentHooks!.push(obj); | |
| return obj; | |
| } | |
| function useState<T>(initialValue: T) { | |
| const stateHook = getNextHook() as StateHookObject<T> || createStateHook(initialValue); | |
| ++global_currentHookIndex!; | |
| return [stateHook.value, stateHook.updater] as const; | |
| } | |
| function MyComponent() { | |
| const [count, updateCount] = useState(0); | |
| setTimeout(() => updateCount(1)); | |
| return '<p>' + count + ' kittens</p>'; | |
| } | |
| alert(doRender(MyComponent)) | |
| setTimeout(() => { | |
| alert(doRender(MyComponent)) | |
| }, 1000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment