From 67d0cbfb63f65019ffbac7dfc2d2d7f8a6986312 Mon Sep 17 00:00:00 2001
From: nparashar150
Date: Sat, 8 Oct 2022 02:34:42 +0530
Subject: [PATCH] * Create useState hook * Use Map for state store management *
Use function caller for state store
---
lib/createElement.js | 4 ++-
lib/index.js | 2 ++
lib/useState.js | 60 +++++++++++++++++++++++++++----
src/components/button/button.js | 9 +----
src/index.js | 63 +++++++++++++++------------------
5 files changed, 87 insertions(+), 51 deletions(-)
diff --git a/lib/createElement.js b/lib/createElement.js
index b4959bc..27f3d1c 100644
--- a/lib/createElement.js
+++ b/lib/createElement.js
@@ -41,7 +41,9 @@ export const createElement = (element, props = {}, ...children) => {
(typeof child === "undefined") |
(child === null)
) {
- _htmlElement.innerHTML = child;
+ if (child) {
+ _htmlElement.innerHTML = child;
+ }
} else {
_htmlElement.appendChild(child);
}
diff --git a/lib/index.js b/lib/index.js
index 156bf98..bf1e194 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -1,10 +1,12 @@
import { createElement } from "./createElement";
import { styleToString } from "./utils/styleToString";
+import { useState } from "./useState";
import { render } from "./render";
const OwnReact = {
createElement,
styleToString,
+ useState,
render,
};
diff --git a/lib/useState.js b/lib/useState.js
index 355600b..c2aeab4 100644
--- a/lib/useState.js
+++ b/lib/useState.js
@@ -1,14 +1,60 @@
/**
*
-// * @param {*} initialState
- * @param {*} _state
+ * @param {T} initialState - Initial state
+ * @param {Function} caller - The component that called this hook
+ * @returns {[T, Function]} - [state, setState]
*/
-export const useState = (initialState) => {
- let _state = initialState;
+export const useState = (initialState, caller) => {
+ // fCState is a function that returns the state of the caller
+ let [_state, index] = fCState(caller, initialState);
+
const _setState = (newState) => {
- if (_state === newState) return;
- _state = newState;
+ if (_state === newState) return; // if the state is the same, do nothing
+ // update the state of the caller with the new state
+ _state = fCState(caller, newState, index)[0];
+
return _state;
};
- return [_state, _setState];
+
+ // return the state
+ const __state = () => _state.get(index);
+
+ return [__state, _setState];
+};
+
+/**
+ *
+ * @param {Function} caller - The component that called this hook
+ * @param {T} state - The state to be set
+ * @param {Number} mapIndex - The index of the state in the map
+ * @returns {[Map, Number]} - [state, index]
+ */
+export const fCState = (caller, state, mapIndex = null) => {
+ // fC = function component
+ // caller is the function component
+ if (typeof caller === "function") {
+ // if the component has no state, create a new map
+ if (!caller._state || caller._state instanceof Map === false) {
+ // if the state is not set, create map of state
+ caller._state = new Map(); // create a map to store the state
+ }
+
+ if (state !== undefined) {
+ if (!mapIndex && caller._state.size === 0) {
+ // if mapIndex is not set, new state is being set
+ caller._state.set(0, state); // set the state and the state
+ return [caller._state, 0];
+ } else if (typeof mapIndex === "number") {
+ caller._state.set(mapIndex, state); // set the state
+ return [caller._state, mapIndex];
+ } else {
+ caller._state.set(caller._state.size, state); // get the state
+ return [caller._state, caller._state.size - 1];
+ }
+ } else {
+ throw new Error("useState must be called with a state value");
+ }
+ } else {
+ throw new Error("useState caller must be of type function");
+ }
};
diff --git a/src/components/button/button.js b/src/components/button/button.js
index 3a4883c..e9e13c8 100644
--- a/src/components/button/button.js
+++ b/src/components/button/button.js
@@ -2,14 +2,7 @@ import OwnReact from "../../../lib/index";
import "./button.css";
const Button = (children) => {
- const handleClick = () => {
- console.log("Button clicked");
- };
- return (
-
- );
+ return ;
};
export default Button;
diff --git a/src/index.js b/src/index.js
index ea06821..6e63fa6 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,6 +3,15 @@ import Button from "./components/button/button";
import "./global.css";
const App = () => {
+ const [count, setCount] = OwnReact.useState(0, App);
+ const [_count, _setCount] = OwnReact.useState(0, App);
+
+ const handleClick = () => {
+ setCount(count() + 1);
+ _setCount(_count() + 2);
+ console.log(count(), _count());
+ };
+
return (
My First Own React App
@@ -10,30 +19,22 @@ const App = () => {
My First Own React App with custom Babel and Webpack config
This is another nesting level
-
-
-
-
- );
-};
-const App2 = () => {
- return (
-
-
My Second Own React App
-
-
-
My Second Own React App with custom Babel and Webpack config
-
This is another nesting level
-
This is another nesting level
-
This is another nesting level
-
+
+
);
};
const App3 = () => {
+ const [count, setCount] = OwnReact.useState(0, App3);
+
+ const handleClick = () => {
+ setCount(count() + 1);
+ console.log(count());
+ };
+
return (
My Third Own React App
@@ -42,31 +43,23 @@ const App3 = () => {
My Third Own React App with custom Babel and Webpack config
This is another nesting level
This is another another nesting level
-
+
);
};
-const App4 = () => {
- return (
-
-
My Fourth Own React App
-
- );
-};
-
OwnReact.render(, "root");
-setTimeout(() => {
- OwnReact.render(, "root");
-}, 5000);
+// setTimeout(() => {
+// OwnReact.render(, "root");
+// }, 5000);
-setTimeout(() => {
- OwnReact.render(, "root");
-}, 10000);
+// setTimeout(() => {
+// OwnReact.render(, "root");
+// }, 10000);
-setTimeout(() => {
- OwnReact.render(, "root");
-}, 15000);
+// setTimeout(() => {
+// OwnReact.render(, "root");
+// }, 15000);