일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- SSR
- Binding
- Groo
- mobx
- 우아한테크러닝
- react.js
- useState
- 상태관리
- 카카오페이
- 리액트를 다루는 기술
- 함수 바인딩
- state
- Modules
- lexicalEnvironment
- Hooks
- JavaScript
- 코딩테스트
- vanilla.js
- Redux
- 리액트
- 취업준비
- CSR
- npm
- 개발일기
- react
- scope
- 취준
- closure
- excutionContext
- 환경오염
- Today
- Total
개발하자
React Hook useState 직접 구현하기! 본문
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
하나의 상태를 보관하는 useState 구현
위의 찾은 자료를 참고하여 하나의 상태를 유지할 수 있는 useState를 구현했다.
아까 App 코드에 useState 대신 내가 만든 useState를 사용하니 잘 동작했다!!
추가한 것
- 초기값인지 확인 후 할당
- 렌더함수 호출
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
'frontend > react.js' 카테고리의 다른 글
드디어 리액트 공부를 시작하며!! (0) | 2022.07.13 |
---|