Skip to content

Instantly share code, notes, and snippets.

@abhiomkar
Last active May 22, 2023 09:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abhiomkar/d0fe117c78b82af9e03b63f3c8aedf97 to your computer and use it in GitHub Desktop.
Save abhiomkar/d0fe117c78b82af9e03b63f3c8aedf97 to your computer and use it in GitHub Desktop.
React useState hook from scratch
const React = (() => {
// {
// 'FooComponent': {
// values: [1, 'apple'],
// hookIndex: 0,
// },
// ...
// }
let hooks = {};
let componentId = "";
const useState = (initVal) => {
if (hooks[componentId] === undefined) {
hooks[componentId] = {};
hooks[componentId].values = [];
hooks[componentId].hookIndex = 0;
}
const hookIndex = hooks[componentId].hookIndex;
if (hooks[componentId].values[hookIndex] === undefined) {
hooks[componentId].values[hookIndex] = initVal;
}
const localIndex = hookIndex;
const localComponentId = componentId;
const setState = (newVal) => {
hooks[localComponentId].values[localIndex] = newVal;
};
const state = hooks[componentId].values[hookIndex];
hooks[componentId].hookIndex = hookIndex + 1;
return [state, setState];
};
const render = (Component) => {
componentId = Component.name;
if (hooks[componentId]) {
hooks[componentId].hookIndex = 0;
}
const c = Component();
c.render();
return c;
};
return {
useState,
render
};
})();
const FooComponent = () => {
const [state, setState] = React.useState(0);
const [color, setColor] = React.useState("red");
return {
render: () => {
console.log("FooComponent:", { state, color });
},
click: () => {
setState(state + 1);
},
changeColor: (color) => {
setColor(color);
}
};
};
let foo = React.render(FooComponent);
foo.click();
foo = React.render(FooComponent);
foo.click();
foo.changeColor("blue");
foo = React.render(FooComponent);
foo.click();
foo = React.render(FooComponent);
const BarComponent = () => {
const [count, setCount] = React.useState(10);
return {
render: () => {
console.log("BarComponent:", { count });
},
click: () => {
setCount(count - 1);
}
};
};
let bar = React.render(BarComponent);
bar.click();
bar = React.render(BarComponent);
bar.click();
bar = React.render(BarComponent);
bar.click();
bar = React.render(BarComponent);
foo.click();
foo = React.render(FooComponent);
bar.click();
bar = React.render(BarComponent);
// Output:
//
// FooComponent: {state: 0, color: "red"}
// FooComponent: {state: 1, color: "red"}
// FooComponent: {state: 2, color: "blue"}
// FooComponent: {state: 3, color: "blue"}
// BarComponent: {count: 10}
// BarComponent: {count: 9}
// BarComponent: {count: 8}
// BarComponent: {count: 7}
// FooComponent: {state: 4, color: "blue"}
// BarComponent: {count: 6}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment