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);