์ฃผ์š” ์ž‘์—…

  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • useState ์„ค๊ณ„ ๋ฐ ๊ตฌํ˜„
      • function ํ˜•ํƒœ์˜ state๊ตฌํ˜„
      • state๋ฅผ destructuringํ•˜๋Š” ๊ณผ์ •์„ ํŒŒ์•…ํ•˜๊ณ  ๊ตฌ์กฐ๋ถ„ํ•ด ํ• ๋‹น์— ๋Œ€ํ•œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ๊ณ ์•ˆ
      • setterํ•จ์ˆ˜๋ฅผ ํ†ตํ•œ ์ƒํƒœ ๊ฐฑ์‹ 
      • ํŒŒ์ด๋ฒ„ ์ƒ์„ฑ ๋‹จ๊ณ„์—์„œ ๊ฐฑ์‹ ๋œ state๊ฐ€์ ธ์˜ค๊ธฐ
    • ๋ฉ˜ํ† ๋‹˜ ๋ฆฌ๋ทฐ ๋ฐ˜์˜

ํ•™์Šต ํ‚ค์›Œ๋“œ

  • ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜
  • useState

๊ณ ๋ฏผ ๋ฐ ํ•ด๊ฒฐ๊ณผ์ •

useState์˜ ๋™์ž‘ ๋ฐฉ์‹๊ณผ ์ด์— ๋”ฐ๋ฅธ ๋ Œ๋”๋ง ๋กœ์ง

๊ธฐ์กด์— ๋‚ด๊ฐ€ ์ง  ๋กœ์ง์„ ๋ณด์ž

import { Root } from "../dom/DomRoot";
 
/**
 *
 * @param {any} initialState
 * @returns {[any, function]}
 */
export function useState(initialState) {
  let state = initialState;
 
  
  const setState = (function () {
    const hostRoot = Root();
    // ํด๋กœ์ €๋กœ state์— ํ•ด๋‹นํ•˜๋Š” index๋ฅผ setState์— ๋ฌถ์–ด๋‘๊ธฐ
    return function (value) {
      state = value;
      hostRoot.reRender();
    };
  })();
 
  return [state, setState];
}

๋‚ด๊ฐ€ ์ฒ˜์Œ ์ง  useState๋ฅผ ๋ณด๋ฉด initialState๋ฅผ state๋ผ๋Š” ๋ณ€์ˆ˜์— ํ• ๋‹นํ•ด๋†“๊ณ  ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, setState๋Š” ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด state์˜ ๊ฐ’์„ ๊ฐฑ์‹ ํ•ด์ค€ ๋‹ค์Œ ๋ฆฌ๋ Œ๋”๋ง์„ ์‹œํ‚ค๋„๋ก ๋กœ์ง์ด ์งœ์—ฌ์ ธ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๋กœ์ง์˜ ๊ฒฝ์šฐ

  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ state๊ด€๋ฆฌ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅ
  • ํ•œ state์— ์—ฌ๋Ÿฌ๋ฒˆ์˜ setState๊ฐ€ ์ผ์–ด๋‚  ๊ฒฝ์šฐ ๋ฐ˜๋ณตํ•ด์„œ ๋ฆฌ๋ Œ๋”๋ง
  • ๋ฆฌ๋ Œ๋”๋งํ•œ ํ›„์— ๊ฐฑ์‹ ๋œ ๊ฒฐ๊ณผ๋ฅผ ์•Œ์ง€ ๋ชปํ•จ ๋“ฑ์˜ ๋ฌธ์ œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ํ•˜๋‚˜์”ฉ ๋ณด์™„ํ•ด๊ฐ€๋ฉด์„œ ๊ตฌํ˜„์„ ์™„์„ฑ์‹œํ‚ค๋ ค๊ณ  ํ•œ๋‹ค.

๋ฌธ์ œ: ๋ฆฌ๋ Œ๋”๋งํ•œ ํ›„์— ๊ฐฑ์‹ ๋œ ๊ฒฐ๊ณผ๋ฅผ ์•Œ์ง€ ๋ชปํ•จ

ํ•ด๋‹น ๋ฌธ์ œ๋Š” state์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋Š” ๋ฌธ์ œ๋ผ ํ•ด๋‹น ๋ฌธ์ œ๋ถ€ํ„ฐ ํ•ด๊ฒฐํ•ด์•ผ ํ–ˆ๋‹ค. ๊ฐ’์ด ๋ณ€ํ•ด๋„ ๋ฆฌ๋ Œ๋”๋ง ๊ณผ์ •์—์„œ ์ƒˆ๋กญ๊ฒŒ ๋ฐ”๋€ ๊ฐ’์„ ๋ Œ๋”๋ง์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค๋ฉด state์˜ ์˜๋ฏธ ์ž์ฒด๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ธฐ์กด ๋‚ด๊ฐ€ ๋งŒ๋“  jsx ํ”„๋กœ์ ํŠธ์˜ jsx ํŠธ๋žœ์ŠคํŒŒ์ผ๋ง๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด

import * as mhReact from "mhreact";
export default function Mainpage() {
  var _mhReact$useState = mhReact.useState(1),
    _mhReact$useState2 = _slicedToArray(_mhReact$useState, 2),
    numbers = _mhReact$useState2[0],
    setNumbers = _mhReact$useState2[1];
  function onClickButton() {
    console.log("click");
    setNumbers(5);
  }
  return mhReact.createElement("div", null, mhReact.createElement("h1", null, "\uBBFC\uD615\uC774\uC758 \uD22C\uB450\uB9AC\uC2A4\uD2B8"), mhReact.createElement("input", {
    type: "text",
    placeholder: "\uD560 \uC77C\uC744 \uC4F0\uC790"
  }), mhReact.createElement("button", {
    onClick: onClickButton
  }, numbers));
}

์ด๋Ÿฐ ์‹์œผ๋กœ ๋‚ด๊ฐ€ useState๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ๋‚˜์˜ค๋Š” ๋ฆฌํ„ด๊ฐ’์ธ ๋ฐฐ์—ด์„ ๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น ํ•˜๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋ถ„ํ•ด ํ• ๋‹น์„ ํ†ตํ•ด ์›์‹œ๊ฐ’์„ state๋กœ ์„ค์ •ํ•ด๋†“์€ numbers์˜ ๊ฒฝ์šฐ numbers์—๋Š” ์›์‹œ๊ฐ’์ด ๋“ค์–ด์˜ค๊ฒŒ ๋˜๊ณ , ์›์‹œ๊ฐ’์€ ๊ธฐ์กด์˜ ๊ฐ’์ด ๋ณ€ํ•ด๋„ ์ƒˆ๋กญ๊ฒŒ ํ• ๋‹นํ•˜์ง€ ์•Š๋Š” ์ด์ƒ ๋ณ€ํ™”๋ฅผ ์•Œ ์ˆ˜ ์—†๋‹ค๋Š” ์ ์ด ๋ฆฌ๋ Œ๋”๋ง๋œ element๊ฐ€ ๋ฐ”๋€ state๋ฅผ ์•Œ ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๋ฅผ ๋‚ณ์•˜๋‹ค.

์‹œ๋„1 : rootFiber์—์„œ global๋กœ state๊ด€๋ฆฌ

rootFiber์— global property๋ฅผ ๋‘๊ณ  ํ•ด๋‹น ๊ฐ์ฒด์— states ํ”„๋กœํผํ‹ฐ๋ฅผ ๋‘๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ rootFiber๊ฐ€ null๊ฐ’์ด ๋‚˜์™”๋‹ค. ์ƒ๊ฐํ•ด๋ณด๋‹ˆ useState์— fiber๋ฅผ ๋‘๊ฒŒ ๋˜๋ฉด ๊ฐ€์žฅ ์ฒ˜์Œ root๋ฅผ Renderํ•  ์‹œ์ ๋งŒ ํ•ด๋„ fiber๊ฐ€ ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์€ ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— UseState์•ˆ์—์„œ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ rootFiber๋ฅผ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋˜๋ฉด null๊ฐ’์ด ๋œฐ ์ˆ˜๋ฐ–์— ์—†์—ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ด useState๋ฅผ ์–ด๋””์„œ ๊ฐ€์ ธ์™€์•ผ ํ• ๊นŒ?

์‹œ๋„2: root์—์„œ global๋กœ state๊ด€๋ฆฌ

root์—์„œ global์ด๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๋‘๊ณ , ์—ฌ๊ธฐ์„œ ๊ฐ state๋ฅผ ์ธ๋ฑ์Šค : ๊ฐ’์˜ ์Œ์œผ๋กœ ์ €์žฅํ•ด๋†“์œผ๋ฉด ์ „์—ญ์—์„œ ๋ชจ๋“  state๋“ค์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํšจ์œจ์ ์ด์ง€ ์•Š์„๊นŒ ์ƒ๊ฐํ–ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ๊ฐ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋งŒ์•ฝ ์‚ฌ์šฉํ•˜๋Š” state์˜ ๊ฒฝ์šฐ์—๋Š” transpiling ๊ณผ์ •์—์„œ ํ•ด๋‹น state๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ์ฐธ์กฐ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.

state = root.global.states[index]

๋”ฐ๋ผ์„œ useState์— ์ด๋Ÿฐ ์‹์œผ๋กœ state๊ฐ’์„ ๋‚ด๋ณด๋‚ด๋„๋ก ํ•˜๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ, ๋ฌธ์ œ๋Š” ํ•ด๋Œ•ํ•˜๋Š” ์ธ๋ฑ์Šค๋ฅผ ํ‚ค๊ฐ’์œผ๋กœ ๊ฐ–๋Š” value๊ฐ€ ๊ฐฑ์‹ ์ด ๋˜์—ˆ์Œ์—๋„ ๋ฆฌ๋ Œ๋”๋ง ํ•˜๋Š” ๊ณผ์ •์—์„œ ์ œ๋Œ€๋กœ ์ฐธ์กฐ๋ฅผ ๋ชปํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ์ด ๋˜ํ•œ ๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น์œผ๋กœ ๊ฐ ๊ฐ’์„ ๊ณ„์† ์›์‹œ๊ฐ’์œผ๋กœ ๊ฐ€์ง€๊ฒŒ ๋˜์„œ์ธ ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค.

๋”ฐ๋ผ์„œ ๋‚˜๋Š” state๋ฅผ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์–ด ๋ณด์•˜๋‹ค.

import { Root } from "../dom/DomRoot";
import { RootFiber } from "../dom/rootFiber";
 
/**
 *
 * @param {any} initialState
 * @returns {[any, function]}
 */
export function useState(initialState) {
  const root = Root();
  if (!root.global.hasOwnProperty("states")) {
    root.global.states = {};
    root.global.statesIdx = 0;
  }
 
  const index = root.global.statesIdx;
  if (!root.global.states.hasOwnProperty(index)) {
    root.global.states[index] = initialState;
  }
  // state = root.global.states[index]
  const state = () => {
    console.log('๋ฃจํŠธ',root); 
    return root.global.states[index]
  }
  const setState = (function () {
    // ํด๋กœ์ €๋กœ state์— ํ•ด๋‹นํ•˜๋Š” index๋ฅผ setState์— ๋ฌถ์–ด๋‘๊ธฐ
    const currentIndex = index;
    return function (value) {
      if(typeof value === 'function'){
        root.global.states[currentIndex] = value(root.global.states[currentIndex])  
        root.reRender();
      } else{
        root.global.states[currentIndex] = value;
        console.log("state Changed", root.global.states[currentIndex]);
        root.reRender();
      }
    };
  })();
 
  root.global.statesIdx++;
 
  return [state, setState];
}

ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ์—๋Š” ๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น์ด ์ด๋ฃจ์–ด์ง€์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— root์— ๋‹ด๊ฒจ์žˆ๋Š” state๋“ค์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ˜„์žฌ๋Š” ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋งŒ ์ ์  ํ• ์ˆ˜๋ก ๋ฌธ์ œ๊ฐ€ ํ•˜๋‚˜๋‘˜์”ฉ ํŠ€์–ด๋‚˜์™”๋‹ค.

map์ด jsx๋กœ ๋ณ€ํ™˜๋  ๋•Œ ๋‚˜์ค‘์— ๋ณ€ํ™˜ํ•˜๋Š” ๊ณผ์ •

<TodoList todoList={todo} />
...
export default function TodoList({ todoList }) {
  return (
    <ul>
      {todoList.map((todo) => (
        <li>{todo}</li>
      ))}
    </ul>
  );
}
 

todo๋ผ๋Š” ๋ฐฐ์—ด๋กœ ๋œ state๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ  ์ด๋ฅผ ๋ฆฌ์•กํŠธ์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ฒจ์ค˜์„œ ๋ฐฐ์—ด์— ๋Œ€ํ•ด map์‹œํ‚จ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ชจ๋‘ ๋ Œ๋”๋ง์‹œํ‚ค๋„๋ก ๋งŒ๋“ค์—ˆ๋‹ค.

export default function TodoList(_ref) {
  var todoList = _ref.todoList;
  return mhReact.createElement("ul", null, todoList.map(function (todo) {
    return mhReact.createElement("li", null, todo);
  }));
}

์ด์— ๋Œ€ํ•œ ํŠธ๋žœ์ŠคํŒŒ์ผ๋ง ๊ฒฐ๊ณผ๋ฌผ์€ ์œ„์™€ ๊ฐ™์ด ๋‚˜์˜จ๋‹ค.

mhReact.createElement(TodoList, {
    todoList: todo
  }));

ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ์ปค์Šคํ…€ ์ปดํฌ๋„ŒํŠธ๋“ค๊ณผ ๋˜‘๊ฐ™์ด ์ƒ์œ„์—์„œ createElement pragma๊ฐ€ ๋ถ™๋Š”๋‹ค. ์—ฌ๊ธฐ์„œ ๋‚ด๊ฐ€ ๋„˜๊ฒจ์ค€ todo๋ผ๋Š” ๊ฐ’์ด props๋กœ ๊ฐ€๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฐ props์— ๋Œ€ํ•ด์„œ ๋ถ„๊ธฐ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์–ด ํƒœ๊ทธ์˜ attribute๋กœ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค์„ ์ œ์™ธํ•œ ๊ฒƒ๋“ค์€ ๋ฐ์ดํ„ฐ๋กœ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ์–ด์•ผ ํ–ˆ๋‹ค.

export function createElement(type, props, ...children) {
  props = devideValidProps(props);
  if (typeof type === "function") {
    if(type.name === "App") return;
    if (props && props.hasOwnProperty("refs")) return type(props.refs);
    return type();
  }
  return new MhElement(type, props, children.flat());
}

์ฒ˜์Œ์— ๋ถ„๊ธฐ์ฒ˜๋ฆฌ ํ•ด๋ณธ ๊ณณ์€ createElement์˜€๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด ํ•จ์ˆ˜๋ฅผ ๋น„๋ฆฌ ์‹คํ–‰์‹œํ‚ค๊ฒŒ ๋œ๋‹ค๋ฉด ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ปค์Šคํ…€ ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ์ด๋ฏธ ๊ตฌ์กฐ๋ถ„ํ•ด ํ• ๋‹น์ด ์ด๋ฃจ์–ด์ง„ ์ƒํƒœ๋กœ root์˜ node๋“ค์ด ํ• ๋‹น๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒํƒœ๊ฐ€ ๋ฐ˜์˜๋  ์ˆ˜ ์—†๋‹ค. ํŠนํžˆ๋‚˜ map ํ•จ์ˆ˜๋ฅผ ๋„๋Š” ๊ณณ์ด ์žˆ๋‹ค๋ฉด ๊ฒฐ๊ตญ map์„ ํ†ตํ•ด ๋ชจ๋“  element๊ฐ€ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์ง€๋‹ˆ ์ƒˆ๋กญ๊ฒŒ ๋ Œ๋”๋ง์ด ์ด๋ฃจ์–ด์ง€์ง€ ์•Š๋Š”๋‹ค.

๋‹ค์Œ์œผ๋กœ๋Š” ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์˜ ๊ฒฝ์šฐ์—๋Š” ํ•จ์ˆ˜ ๊ทธ๋Œ€๋กœ ํ’€์ง€ ์•Š๊ณ  ๋‘๊ณ , ๋‚˜์ค‘์— ๋ Œ๋”๋ง์„ ํ•˜๋Š” ๊ณผ์ •์—์„œ fiber๋ฅผ ๋งŒ๋“ค์–ด๋‚ผ ๋•Œ ํ’€์–ด๋‚ด๋ฉด ๋˜์ง€ ์•Š์„๊นŒ ์ƒ๊ฐํ–ˆ๋‹ค.

export function destructuringFunctionalComponentWithRef(element){
  const duplicated = {}
  Object.entries(element.props.refs).forEach(([ref,val]) => {
    if(typeof val === "function") duplicated[ref] = val();
  })
  return element.type(duplicated)
}

์ด ๊ณผ์ •์—์„œ๋„ ์›๋ž˜๋Š” element์˜ ref๋ฅผ ๋ณ€๊ฒฝํ–ˆ๋‹ค๊ฐ€ ์ฐธ์กฐ๋˜์–ด ์žˆ๋Š” ๊ฐ์ฒด์˜ ๊ฐ’์ด ์˜๊ตฌํžˆ ๋ณ€ํ–ˆ๋˜ ๋ฌธ์ œ๋„ ์žˆ์–ด ๋ช‡์‹œ๊ฐ„๋™์•ˆ ์ฉ”์ฉ”๋งค๋‹ค duplicated๋ผ๋Š” ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์„ ํ†ตํ•ด์„œ ์ƒˆ๋กญ๊ฒŒ ๋ณต์‚ฌํ•˜์—ฌ element๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋„๋ก ํ–ˆ๋‹ค.

์•„๋ฌดํŠผ ์ด ํ•จ์ˆ˜๋Š” createFiberFromElement์—์„œ ์ด๋ฅผ destructuringํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ์—ˆ๋‹ค.

export function createFiberFromElement(
  element,
  parent = null,
  index = 0,
  key = null
) {
  //์•ž์—์„œ state ์—†๋Š” ์• ๋“ค์€ ๋‹ค ํ’€์–ด๋†“์Œ
  if (typeof element.type === "function") element = destructuringFunctionalComponentWithRef(element)
  if (typeof element !== "object") {
    parent.textNode = element;
    return null;
  }
...

์ด๋ฅผ ํ†ตํ•ด functional component๋ฅผ ๋งŒ๋‚ฌ์„ ๊ฒฝ์šฐ, ํ•ด๋‹น ์ฐธ์กฐ๊ฐ’์„ ๋ฏธ๋ฆฌ destructuringํ•˜์ง€ ์•Š๊ฒŒ ํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ Œ๋”๋ง์„ ํ•  ๋•Œ๋งˆ๋‹ค ํ’€๊ณ  ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ด์„œ state๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋„๋ก ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ state๋ฅผ ํ•จ์ˆ˜ํ˜•์œผ๋กœ ๋งŒ๋“ค๋ฉด์„œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. ๊ฐ€์žฅ ํฐ ๋ฌธ์ œ๋Š” setterํ•จ์ˆ˜์— ๋Œ€ํ•ด์„œ ์ฝœ๋ฐฑ์„ ๋„ฃ๊ฒŒ ๋˜๋ฉด prev๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ, prev๊ฐ’์„ ์ฝœ๋ฐฑ์— ์ธ์ž๋กœ ๋„ฃ๋Š” ๊ณผ์ •์—์„œ state ํ•จ์ˆ˜ ์ž์ฒด๊ฐ€ ๋“ค์–ด๊ฐ€๊ฒŒ ๋˜๋ฏ€๋กœ, ์ •์ƒ์ ์ธ ๊ฐฑ์‹ ์ด ์•„๋‹Œ ํ•จ์ˆ˜ํ˜•์œผ๋กœ๋งŒ ๊ฐฑ์‹ ์ด ๋˜์—ˆ๋‹ค.

const setState = (function () {
    // ํด๋กœ์ €๋กœ state์— ํ•ด๋‹นํ•˜๋Š” index๋ฅผ setState์— ๋ฌถ์–ด๋‘๊ธฐ
    const currentIndex = index;
    return function (value) {
      if(typeof value === 'function'){
        root.global.states[currentIndex] = value(root.global.states[currentIndex])  
        root.reRender();
      } else{
        root.global.states[currentIndex] = value;
        console.log("state Changed", root.global.states[currentIndex]);
        root.reRender();
      }
    };
  })();

์•„์ง ํ•ด๋‹น ํ•จ์ˆ˜์˜ prev๋Š” ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋ฐ, ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•ด์•ผ ํ• ์ง€ ๊ณ„์† ๊ณ ๋ฏผ์ค‘์— ์žˆ๋‹ค..