|
| 1 | +let React = (function() { |
| 2 | + let global = {}; // define a global variable where we store information about the component |
| 3 | + let index = 0; // index to keep track of the component's state |
| 4 | + function render(Component) { |
| 5 | + global.Component = Component; |
| 6 | + const instance = Component(); // get the instance of the component |
| 7 | + index = 0; |
| 8 | + instance.render(); // call the component's render function |
| 9 | + |
| 10 | + global.instance = instance; // store the component's instance for any future calls of the component's functions |
| 11 | + return global; // return the global variable |
| 12 | + } |
| 13 | + |
| 14 | + function useState(initialState) { |
| 15 | + if (!global) { |
| 16 | + throw new Error("Need a global"); |
| 17 | + } |
| 18 | + |
| 19 | + if (!global.hooks) { |
| 20 | + global.hooks = []; // this array holds the state of the component |
| 21 | + } |
| 22 | + |
| 23 | + const hooks = global.hooks; |
| 24 | + const currentState = global.hooks[index] || initialState; |
| 25 | + hooks[index] = currentState; // memoize the state for future access |
| 26 | + firstrender = true; |
| 27 | + |
| 28 | + const setState = (function() { |
| 29 | + let currentIndex = index; // copy the index so each useState call will have it's own "closed" value over index (currentIndex) |
| 30 | + return function(value) { |
| 31 | + global.hooks[currentIndex] = value; |
| 32 | + render(global.Component); //re-render the component after state change |
| 33 | + }; |
| 34 | + })(); |
| 35 | + index = index + 1; |
| 36 | + return [currentState, setState]; |
| 37 | + } |
| 38 | + |
| 39 | + function useEffect(cb, deps) { |
| 40 | + const hooks = global.hooks; |
| 41 | + |
| 42 | + // getting older dependencies from the hooks array since |
| 43 | + // we are storing dependencies as a sub-array inside the hooks array |
| 44 | + let oldDeps = hooks[index]; |
| 45 | + |
| 46 | + // if no dependencies are provided, |
| 47 | + // the callback function will be called at each re-render |
| 48 | + let hasChanged = true; |
| 49 | + |
| 50 | + if (oldDeps) { |
| 51 | + // checking if the old dependencies are different from older dependencies |
| 52 | + hasChanged = deps.some((d, index) => !Object.is(d, oldDeps[index])); |
| 53 | + } |
| 54 | + if (hasChanged) cb(); // if dependencies has changed call the callback function. |
| 55 | + |
| 56 | + hooks[index] = deps; //store dependencies inside the hooks array as a sub-array |
| 57 | + index++; // increment index for any other useEffect calls |
| 58 | + } |
| 59 | + |
| 60 | + return { render, useState, useEffect }; |
| 61 | +})(); |
| 62 | + |
| 63 | +function Component() { |
| 64 | + |
| 65 | + // Component is called at each re-render. index is reset to 0. |
| 66 | + |
| 67 | + const [count, setCount] = React.useState(0); |
| 68 | + // hooks: [0], currentIndex: 0, Incremented Index: 1 |
| 69 | + |
| 70 | + const [word, setWord] = React.useState(""); |
| 71 | + // hooks: [0, ''], currentIndex: 1, Incremented Index: 2 |
| 72 | + |
| 73 | + const countSetter = () => { |
| 74 | + setCount(count + 1); |
| 75 | + }; |
| 76 | + |
| 77 | + const wordSetter = word => { |
| 78 | + setWord(word); |
| 79 | + }; |
| 80 | + |
| 81 | + function render() { |
| 82 | + console.log(`Count is: ${count}, Word is: ${word}`); |
| 83 | + } |
| 84 | + |
| 85 | + React.useEffect(() => { |
| 86 | + console.log("hookssss!!!!"); |
| 87 | + }, [count, word]); |
| 88 | + // hooks: [0, '', [0, '']], currentIndex: 2, Incremented Index: 3 |
| 89 | + |
| 90 | + React.useEffect(() => { |
| 91 | + console.log("hooks2!!!!!"); |
| 92 | + }, []); |
| 93 | + // hooks: [0, '', [0, ''], [] ], currentIndex: 3, Incremented Index: 4 |
| 94 | + |
| 95 | + return { render, countSetter, wordSetter }; |
| 96 | +} |
| 97 | + |
| 98 | +const global = React.render(Component); // hooks: [ 0, '', [ 0, '' ], [] ] |
| 99 | +global.instance.countSetter(); // hooks: [ 1, '', [ 1, '' ], [] ] |
| 100 | +global.instance.countSetter(); // hooks: hooks: [ 2, '', [ 2, '' ], [] ] |
| 101 | +global.instance.countSetter(); // hooks: [ 3, '', [ 3, '' ], [] ] |
| 102 | +global.instance.wordSetter("yooo"); // hooks: [ 3, 'yooo', [ 3, 'yooo' ], [] ] |
| 103 | +global.instance.wordSetter("ssup"); // hooks: [ 3, 'yooo', [ 3, 'yooo' ], [] ] |
0 commit comments