어수룩하게 배운 리액트로 개발을 하면서 아무것도 모른채 사용하던 useState, useEffect와 같은 use
로 시작하는 함수인 React Hooks에 대해서 공부해보려고 한다.
일단 hook을 왜 쓰는건지 알아보자. 뭔가 유용한 점이 있으니 쓰는게 아닐까?
hook이 왜 리액트에서 유용한건지.. 알아가보자!!
리액트를 최근 배운 사람이라면 새로운 컴포넌트를 만들 때 const 컴포넌트 이름 = () => { }
형태로 만들어왔을 것이다. 이 형태는 js를 배웠다면 알겠지만 화살표 함수라고 불리는 코드 형태다. (funtion키워드를 사용해서도 만들 수 있음!) 그래서 이런 컴포넌트를 함수형 컴포넌트라고 한다. 함수처럼 생겼으니까 그렇게 부른다!
그런데 원래 과거의 리액트는 함수형 컴포넌트가 아니라 클래스형 컴포넌트였다고 한다. 나는 사용해본 적이 없지만.. class 컴포넌트 이름 extends React.Component = {}
형태로 사용했다고 한다.
그런데 왜 지금은 클래스형 컴포넌트보다 함수형 컴포넌트를 주로 사용하는 걸까?
리액트 공식 문서를 읽으면 클래스형 컴포넌트의 단점이 여러개 있다. 그런데 사실 나는 클래스형 컴포넌트를 사용해본적이 없어서 사실 어려움에 대해서 이해하기 어려웠다.
그런데 단 하나 이해할 수 있던 어려움이 있었는데 그건 클래스의 this
키워드이다. js로 클래스를 작성하다보면 this사용에 항상 어려움을 겪었다. js의 this는 c++이나 다른 프로그래밍 언어의 this와는 다르게 동작했고, 규칙이 있긴 했지만 그 규칙을 매 오류마다 찾아다니기가 정말 어렵다.
그리고 리액트의 클래스형 컴포넌트에서도 이와 유사한 어려움을 겪은 사람들이 있었는지 클래스형 컴포넌트에서 함수형 컴포넌트를 사용하게 된 것이다.
사실 함수형 컴포넌트도 단점이 있었다. 함수형 컴포넌트는 변수를 저장할 수 없다는 것이다. 이게 무슨 말이냐..?! 하면 아래의 예제를 읽어보자.
함수형 컴포넌트를 만들어 내부에 let a = 1
이라는 변수를 선언했다고 하자.(이 변수는 웹페이지에 보인다) 그리고 버튼을 누르면 a = 2
가 되도록 재할당을 해주는 코드가 있다.
이 컴포넌트는 처음 마운트가 되어 컴포넌트 내부의 코드들을 전부 실행한다. 처음 a는 1이고, 사용자가 버튼을 눌러서 a를 2로 바꿨다고 하자.
그런데 이 컴포넌트의 부모 컴포넌트가 리렌더링이 되면 이 컴포넌트도 다시 리렌더링이 된다. 리렌더링이 된다는 것은 함수형 컴포넌트의 내부가 처음부터 다시 작성되어 실행된다는 의미다. 그러면 분명 사용자는 버튼을 눌러서 a를 2로 바꿨음에도 불구하고 let a = 1
코드로 인해 a는 1로 돌아가게 된다.
즉 처음에 말했던 변수를 저장하지 못한다는 단점이 바로 보이는 것이다.
그러면 이걸 어떻게 해결했을까? 그건 바로 React Hooks의 도입이다.
함수형 컴포넌트에 변수를 저장하고 리렌더링이 되어도 유지할 수 있도록 하는 hook이 도입된다. 그것이 바로 항상 사용하던 useState
인 것이다.
우리가 평소에 사용하던 let, const 키워드로 변수를 선언하는 것이 아닌 useState를 이용해서 변수를 선언해주면 리렌더링 되면 바로 휘발되는 변수가 아닌 계속 유지되는 변수를 사용할 수 있는 것이다!
hook은 useState외에도 useEffect, useContext등 정말 많은 hook이 있다. 그리고 이런 hook들은 use
키워드가 접두사이다.
그리고 왜 이름이 hook이냐 하면 함수형 컴포넌트를 클래스형 컴포넌트처럼 사용하기 위해 클래스형 컴포넌트에서 사용하던 기능들을 뽑아서(hook!) 가져온 거라 이름이 hook이다. 이름의 유래가 이해를 돕는 것 같다.