JSConf.Asia 2019에서 Shawn Wang이 발표한 내용을 정리해보았습니다.
안녕하세요, 휴먼스케이프 개발자 Tasha입니다. React Hooks에 대한 내용은 이미 두 번이나 포스팅에서 자세히 잘 다뤄졌지만, 그럼에도 불구하고 흥미로운 내용이 있어 또 hooks를 주제로 삼게 되었습니다! :)
Shawn Wang — [JsConf.Asia : Getting Closure on React Hooks]
이번에 소개해 드릴 내용은, 올해(2019년) 싱가폴에서 열린 JSConf에서 Netlify의 개발자인 Shawn이 발표한 Getting Closure on React Hooks인데, 자바스크립트 Closure개념을 이용하여 Hooks를 직접 구현해보는 내용입니다. 평소 useState와 같은 메소드를 사용하면서 이게 어떻게 작동이 되는 것인지 궁금증이 있었는데 직접 구현하는 과정을 통해서 hooks가 어떤 원리로 작동되는지도 알게되고, 자바스크립트 클로저 개념도 다시 들여다 볼 수 있어서 매우 만족스러웠습니다.
먼저 React Hooks를 구현해 보기 전에, 클로저의 개념을 다시 되짚고 넘어갑니다. 클로저의 개념이 가장 잘 설명되었다고 판단되는 W3Schools에서 정의한 개념은 다음과 같습니다.
“Closure makes it possible for a function to have ‘private’ variables.”
이런식으로 함수를 구성하면, add에 할당 된 함수는 생성당시 외부스코프에 있는 변수를 기억해 호출될때마다 foo의 값에 접근 가능하고, 이 foo의 값은 외부에서는 접근이 불가능하기 때문에 W3schools의 정의와 같이 private한 변수를 가질 수 있게 되는 것입니다.
이와 같은 자바스크립트 클로저 개념을 이용해 구현한 useState는 다음과 같습니다.
useState함수에서 리턴한 state값을 통해서만 _val 변수에 접근 가능하게 하고, useState함수에서 리턴한 setState값을 통해서만 _val 변수를 변경하도록 하는 것입니다.
위의 함수를 이용해 React를 구현한 내용은 다음과 같습니다.
React함수의 메소드를 이용해서만 _val 변수에 접근이 가능하도록, React함수 내부에 useState와 render함수를 넣어놓고, 간단한 click메소드만 실행하는 Component함수를 구현한 것입니다.
이 상태에서 state가 하나 이상이 되면 어떨까요?
이렇게 useState만 추가하게 되면 같은 변수_val에 저장하기 때문에 의도하지 않은 방식으로 결과가 출력됩니다. 따라서 변수는 배열 이미지로 확장될 필요가 있습니다.
이런식으로 변수 _val을 배열과 index를 이용해 저장시켜주고, 저장된 다음에는 index를 증가시켜 state가 저장되는 공간이 겹치지 않도록 해주었습니다. 그러나 결과는 처음에는 제대로 count에만 새로운 변수가 할당되도록 되었지만 두번째에는 또 의도하지 않은대로 담깁니다. 이는 App컴포넌트가 렌더될때마다 useState함수를 호출하게 되고, 그때마다 index를 증가시키기 때문입니다. 따라서 render할때마다 index를 다시 초기값으로 돌려주어야합니다.
그래도 결과값이 이상하게 찍힙니다.. 왜냐하면 setState(click, type메소드)의 인덱스 값이 유동적이기 때문에 render된 후 증가하는 index값에 영향을 받아 원래 의도했던 배열의 첫번째, 두번째값에 저장되는 것이 아니라 증가된 index에 저장되기 때문입니다.
따라서 또 클로저 개념을 이용해서 setState안의 index값이 useState에 의해 변하지 않도록 freeze시켜줍니다.
이렇게 변경시켜주면 setState가 생성될 당시의 index(state가 할당된 당시의 index)를 기억하게 되고, setState가 호출될 때 이 값을 변화시키기 때문에 드디어 정상적으로 작동하게 됩니다!
React Hooks 규칙 중에 hooks를 최상위에서만 호출하고 반복문 또는 조건문안에서 호출하지 말라는 규칙이 있는데 앞에서 구현한 개념을 보면 그 이유를 이해하실 수 있으실 겁니다. render될때마다 특정 index에 state가 순서대로 할당되므로 최상위에서 불러야 하는 것입니다.
여기까지가 자바스크립트의 클로저개념으로 구현한 Hooks 내용이었습니다. 원본 영상에는 위에서 구현한 useState말고도 useEffect구현 내용도 있으니 궁금하신분들은 youtube에서 참고해보세요! 긴 글 읽어주셔서 감사합니다 :)
[참조] https://www.youtube.com/watch?v=KJP1E-Y-xyo
Get to know us better! Join our official channels below.
Telegram(EN) : t.me/Humanscape KakaoTalk(KR) : open.kakao.com/o/gqbUQEM Website : humanscape.io Medium : medium.com/humanscape-ico Facebook : www.facebook.com/humanscape Twitter : twitter.com/Humanscape_io Reddit : https://www.reddit.com/r/Humanscape_official Bitcointalk announcement : https://bit.ly/2rVsP4T Email : support@humanscape.io