개발하자

React Hook useState 직접 구현하기! 본문

frontend/react.js

React Hook useState 직접 구현하기!

hyesun 2022. 7. 13. 21:06

 

useState 는 무엇일까?

 

공식문서에는 Hook과 useState에 대해서 아래와 같이 설명하고 있다.

 

Hook이란?
 Hook은 특별한 함수입니다.

useState
state를 함수 컴포넌트 안에서 사용할 수 있게 해줍니다.

 

 


 

 

왜 사용하는 것인가?

 

왜인지를 생각해봤을 때 리액트는 함수내에서 변경이 있는 상태를 저장할 수 없다.

 

함수내의 변경이 생기면 함수전체를 다시 렌더링 하기 때문이다.

 

그럼 상태 변수를 유지 할 수 없기 때문에

 

함수 외부에서 상태를 유지해줄 함수나 객체가 필요하다.

 

 

 


 

 

어떻게 사용하는 것인가?

 

클론코딩 강좌를 들으며 useState의 사용법을 배웠다.

 

아래 코드 처럼 사용하면 손쉽게 상태를 저장하고 변경할 수 있다.

 

import { useState } from "react";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);

  return (
    <div className="App">
      <header className="App-header"></header>
      <div className="counter">
        <h2>{count}</h2>
        <button onClick={() => setCount(count + 1)}>PLUS</button>
      </div>
    </div>
  );
}

export default App;

 

리액트에서 실행한 화면이다.

 


 

 

예상한 구조

 

내가 예상한 구조는 이랬다.

 

하지만 역시나 제대로 돌아가지 않았다.

const obj = {
  state: null,
  useState: (s) => {
    this.state = s;

    const setState = (newState) => {
      this.state = newState;
    };

    return [this.state, setState];
  },
};

 

 

this가 제대로 바인딩 되지 않아서 프로퍼티를 찾을 수 없다는 에러가 발생했다.

 

그래서 코드를 찬찬히 살펴보니 useState의 값으로 arrow function을 사용해서 this가 global로 돼 있었다.

 

(this에 관한 이야기도 조만간 포스팅해야겠다!)

 

그래서 코드를 변경했다.

 

const myReact = {
  state: null,
  useState: (s) => {
    this.state = s;

    const setState = function(newState) {
      this.state = newState;
    };

    return [this.state, setState];
  },
};

 

this 문제는 해결 됐지만 역시나 제대로 동작하지 않았다.

 

 

 

 
 

useState 구현 찾아보기!

 

어떻게 구현한 것인지 궁금해서 일단 react의 github에서 코드를 확인했다.

 

함수 내부 구현은 숨김처리 되어 찾기 힘들었다.

 

그래서 검색을 하던 중 나와 비슷하게 구현 한 글을 발견했다.

 

https://www.codementor.io/@lizraeli/implementing-the-usestate-hook-13o3wjkh3j

 

Implementing the useState Hook | Codementor

Introduction I felt uneasy the first time I read about hooks (https://reactjs.org/docs/hooks-intro.html) in React. Their inner workings seemed too magical. I remember looking at a simple example...

www.codementor.io

 

 


 
 

하나의 상태를 보관하는 useState 구현

 

위의 찾은 자료를 참고하여 하나의 상태를 유지할 수 있는 useState를 구현했다.

 

아까 App 코드에 useState 대신 내가 만든 useState를 사용하니 잘 동작했다!!

 

추가한 것

  1. 초기값인지 확인 후 할당
  2. 렌더함수 호출

 

const MyReact = {
  state: null,
  useState: function (s) {
    if (this.state === null) this.state = s;

    const setState = (newState) => {
      this.state = newState;

      root.render(<App />);
    };

    return [this.state, setState];
  },
};

 

실행화면

 

 

 

상태가 변경 되고 나서 새롭게 화면이 렌더링 돼야한다.

 

그래야 새로운 값이 화면에 적용되기 때문이다.

 

그래서 render 함수를 사용해서 화면을 새롭게 그릴 수 있도록 했다.

 

 

 

react-dom 에 대해서는 아직 잘 알지 못해서

 

이 부분에 대해서는 추가학습이 필요하다.

 

어렴풋이는 알고있지만 확실히는 모르는 개념이라 꼭 확인하고 공부를 해야겠다!

 

 

 


 

 

여러개의 상태를 유지하는 useState 구현

 

useState는 여러개의 상태를 유지할 수 있다.

 

그렇게 되도록 구현해 보았다.

 

const MyReact = {
  stateList: [],
  currentIdx: 0,
  useState: function (initValue) {

    if (this.currentIdx === this.stateList.length) {
     
        const state = {
        value: initValue,
        setState(newValue) {
        
          state.value = newValue;
          MyReact.currentIdx = 0;
          root.render(<App />);
        },
      };

      this.stateList.push(state);
    }

    const currentState = this.stateList[this.currentIdx];
    this.currentIdx++;

    return [currentState.value, currentState.setState];
  },
};

 

 

실행화면

 

 

 

currentIdx 변수를 이용해서 상태가 변경되면 0으로 변경하도록 구현했다.

 

그렇게 하면 다시 함수를 실행할때 0번 상태 정보부터 반환 할 수 있다.

 

 

 


 

 

 

 

 

 

실제 구현은 다른 부분이 있을 것이라 생각한다. 

 

렌더 함수 호출 방식, 여러개의 상태를 유지하는 방식 등등 

 

그래도 내부 구조를 이렇게나마 구현하고 생각해볼 수 있어서 재밌었다.

 

전체 코드는 아래 링크에서 볼 수 있다!!

 

 

https://github.com/hyesunie/react_study/tree/master/use_state/my-app/src

 

GitHub - hyesunie/react_study: React.js 학습

React.js 학습. Contribute to hyesunie/react_study development by creating an account on GitHub.

github.com

 

'frontend > react.js' 카테고리의 다른 글

드디어 리액트 공부를 시작하며!!  (0) 2022.07.13
Comments