(출처: https://ko.reactjs.org/docs/hooks-overview.html)
React Hooks는 함수 컴포넌트에서 React state와 생명주기 기능(lifecycle features)을 “연동(hook into)“할 수 있게 해주는 함수입니다. Hook은 class 안에서는 동작하지 않습니다. 대신 class 없이 React를 사용할 수 있게 해주는 것입니다.
-> 기존에는 state를 사용하기위해서 함수형 컴포넌트를 클래스 형식으로 바꾸어줘야 했습니다. 하지만 hooks는 함수형에서도 state를 변경할 수 있게 해주는 리액트에 새로 추가된 기능입니다. 그렇기 때문에 hooks는 클래스 컴포넌트에서 작동하지 않습니다.
hooks의 예시 중 대표적인 것이 useState 입니다. state 변수, 해당 변수를 갱신할 수 있는 함수 이 두 가지 쌍을 반환합니다. 이것이 바로 const [count, setCount] = useState()라고 쓰는 이유입니다. 클래스 컴포넌트의 this.state.count와 this.setState와 유사합니다. 이를 state hooks라고 합니다.
React 컴포넌트 안에서 데이터를 가져오거나 구독하고, DOM을 직접 조작하는 작업을 이전에도 종종 해보셨을 것입니다. 우리는 이런 모든 동작을 “side effects”(또는 짧게 “effects”)라고 합니다. 왜냐하면 이것은 다른 컴포넌트에 영향을 줄 수도 있고, 렌더링 과정에서는 구현할 수 없는 작업이기 때문입니다.
클래스 컴포넌트에서 componentDidMount 그리고 componentDidUpdate로 데이터를 가져오는 것을 수행할 수도 있습니다. 그러나, 같은 componentDidMount 메서드라도 이벤트 리스너를 설정하는 것과 같은 관계없는 일부 로직이 포함될 수도 있으며, componentWillUnmount에서 cleanup을 수행하기도 합니다. 함께 변경되는 상호 관련 코드는 분리되지만 이와 연관 없는 코드들은 단일 메서드로 결합합니다. 이로 인해 버그가 쉽게 발생하고 무결성을 너무나 쉽게 해칩니다.
-> 예를 들면 기존에 클래스 컴포넌트에서 componentDidMount 그리고 componentDidUpdate를 할 때 같은 로직이 들어가는 경우도 있을 수 있기 때문에 조금 더 직관적으로 정리된 상태를 만들기 위해서 사용하는 것이라고 생각합니다. 이를 hooks 에서는 useEffect를 사용하여 해결합니다. 리액트 컴포넌트에는 일반적으로 두 종류의 side effects가 있습니다. 정리(clean-up)가 필요한 것과 그렇지 않은 것. 정리가 필요하지 않은 것에는 componentDidMount와 componentDidUpdate 가 있습니다.
정리가 필요한 것은 componentWillUnmount가 있습니다. 이는 useEffect 안에서 함수실행으로 정리가 필요하지않은 componentDidMount와 componentDidUpdate를 실행하고return 값으로 정리가 필요한 함수를 구현함으로써 해결합니다.
공식문서와 제가 생각한 것을 화살표로 구분해서 정리를 해보았습니다. 제가 이해한 것이 맞는지는 확신이 없기 때문에 계속 글을 보면서 수정할 계획입니다.
React Hooks를 실습해보기 위하여 코드스테이츠에 베타버전으로 올라온 Cmarket sprint를 실습해보았습니다. 쇼핑몰 스프린트로 상품을 장바구니에 담고, 총가격을 계산하는 두개의 웹페이지로 구성되어있습니다. 클릭을 하면 장바구니에 담긴 물건의 개수를 변경해야하고 장바구니 페이지를 클릭하면 담은 물건의 개수와 물건 종류를 표시해야합니다.
2021년 4월 4일 장바구니에 담는 품목의 개수와 종류는 잘 표현하였지만 같은 품목을 여러번 클릭할 경우 해당 품목의 개수가 증가하는 useState로 로직을 짜는 부분에서 막혔습니다. "개수": cartItems.map(el => el.itemId === itemId).length === 0 ? itemCount : setItemCount(itemCount + 1)
이런식으로 삼항 연산자를 사용하여 품목을 클릭할 경우 cartItems에 추가되는데 추가된 품목이 없을 경우 새롭게 itemCount를 할당해주고(itemCount는 초기값 1입니다.) 기존에 품목이 들어있을 경우에는 setItemCount(itemCount + 1)로 값을 증가시켜주고 싶었는데 증가가 되지 않았습니다. 이는 시간이 나는대로 로직을 작성해보며 글을 수정할 계획입니다.
[2021-04-25] https://github.com/alstjd8826/im-sprint-cmarket-hooks 수정완료 했습니다. input 태그의 타입이 number이면 자동으로 증감되는 값을 가져올 수 있어서 기존의 cartItems의 값을 useState를 이용하여 증가된 값으로 상태를 바꿔주면 증감이 표시되게 만들었습니다.
React Hooks를 짧게 공부했습니다. 기존에 클래스 컴포넌트로 만들어버린 것들은 다시 고치는 것이 더 힘들겠지만 아직 함수형 컴포넌트인데 state를 변경해야할 경우라면 클래스로 바꾸지 않고 바로 state를 변경할 수 있기 때문에 hooks가 정말 효율적일 것 같다는 생각을 했습니다.
코드스테이츠 커리큘럼은 많은 내용을 단기적으로 학습해야하기 때문에 어쩔수 없이 특정 내용마다 배움의 깊이가 얕을 수 밖에 없습니다. 처음 배울 때는 어려워서 이해도 안되고 컴퓨터를 쳐다보기 싫고 그랬는데 주말, 주중 저녁 시간을 통하여 이해가 되지않는 부분을 틈틈히 개인 학습하고 다시 학습하면서 이해를 하니까 재미가 생겨서 계속 이런방식으로 학습을 할 계획입니다.