리액트 커스텀 훅 사용 팁

2021. 11. 30. 01:34웹 프론트엔드 개발 노하우/리액트 노하우

이 글은 아래 링크의 내용을 바탕으로 작성되었습니다.

https://www.youtube.com/watch?v=J-g9ZJha8FE

 

useRef 를 사용하여 디펜던시 문제 해결하기

 

 

위와 같은 코드는 리액트 코드를 작성하면서 심심치 않게 볼 수 있습니다. useEffect 안에서 사용하는 함수가 외부 함수라서 이를 useEffect 에 넣어버리고 의존성에 등록해두지 않으면 linter 가 이를 지적할 것입니다. 해당 함수가 업데이트 될 필요가 있다고 합시다. 이때 useEffect 안에서 상태를 바꾸는 로직이 있다면 리렌더링이 수행될 것이고, 해당 외부함수가 useCallback 처리 되어 있지 않으면 매번 아예 새로 생성될 것이기 때문에 무한 렌더링의 수렁에 빠지게 됩니다.

 

 

하지만 그렇다고 useCallback 처리를 하는 것도 한계가 있습니다. 분명 해당 함수는 그 내용이 업데이트 되어야 할 필요가 있습니다. 하지만 useCallback 을 쓰더라도 만일 해당 함수 안에서 다른 함수를 가져다 쓰고 있다면, 그 가져다 쓰는 함수에 대해서도 useCallback을 써야 하는 악순환이 일어납니다.

 

 

이때 사용할 수 있는 패턴이 useRef 를 이용하는 것입니다. useRef 로 생성한 ref 객체는 컴포넌트가 리렌더링되더라도 다시 생성되지 않고 기존의 것을 사용합니다. 그리고 ref.current 이런 식으로 'current'라는 속성을 통해 생성한 함수가 업데이트 될 때마다 그 업데이트 된 함수를 가져다 사용할 수 있습니다.

 

 

 

useReducer 를 이용하여 더 안정적으로 상태 변경하기

 

많이들 useState 훅이 반환하는 setState 를 활용한 상태 변경이 더 단순하고 이에 더 익숙해져 있을 것이라 생각하지만, setState는 그 자체로는 매우 위험할 수도 있는 메서드입니다. 어떤 인자가 들어오든, 별도의 예외처리 없이 그 값 그대로 상태를 업데이트 해버릴 수 있으니까요. 물론 커스텀 훅등을 이용해서 상태변경 인터페이스를 구축하고 setState 가 동작하도록 만들 수 있지만, 문제는 이를 강제할 수 없다는 점에 있습니다.

 

useReducer 를 쓰게 되면 강제적으로 상태를 변경하는 데 쓰일 인터페이스로서의 리듀서 함수를 만들지 않을 수 없게 됩니다. 여기서도 set 동작을 그대로 수행할 수도 있지만, 상태변경 인터페이스를 만드는 것을 강제한다는 점에서 setState 보다 안전한 선택이 될 수 있을 것입니다.

 

 

Multi-Contexts 를 활용하여 전역 상태로 인한 리렌더링 줄이기

 

리액트의 createContext 훅을 활용하여 컨텍스트 객체를 만들고 Provider 를 통해 상태를 넘겨주면 해당 상태는 변경과 동시에 해당 상태를 사용하는 모든 곳에서 리렌더링이 일어나게 만드는 전역 상태가 됩니다. 문제는 단순히 setState 나 dispatch 만 쓰는 컴포넌트 상에서도 관련 상태가 변화하면 리렌더링이 수행된다는 점입니다.

 

 

(출처 : https://www.youtube.com/watch?v=J-g9ZJha8FE)

 

이를 막기 위해 state 와 상태변경 메서드를 다른 컨텍스트의 Provider 로 넘겨주는 방법을 사용할 수 있습니다. 리덕스가 이러한 방법을 채택하고 있고, 상태변경 메서드 자체는 그 값이 바뀔 일이 없으니 그것만 사용하는 컴포넌트 상에서는 전역 상태 변경에 따른 리렌더링이 일어나지 않게 됩니다.

 

 

여러 전역 상태를 하나의 'store'로 관리하기

 

createContext 를 여러번 호출하여 컨텍스트를 여러개 만들고, 프로바이더도 여러개 사용하다 보면 코드가 자칫 지저분해지기 쉽습니다. 게다가 매번 useContext 를 쓸 때마다 컨텍스트 객체를 불러와서 사용하는 것은 귀찮고 코드 양을 늘리게 되죠.

 

 

같이 사용되어야 할 context 끼리 묶어서 'store' 를 만드는 것이 좋은 대안이 될 수 있습니다. Provider, state 를 불러오는 훅, dispatch를 불러오는 훅을 한번에 리턴하는 store 훅을 만들면 더 깔끔한 코드로 전역 상태를 이용할 수 있습니다.

 

 

로컬스토리지로 Persistency 관리하기

 

전역 상태들은 매우 중요한 데이터들이지만 새로고침 하면 이들이 완전히 다 날아가버리는 문제점이 있습니다. 전역 상태를 생성, 변경할 때마다 로컬 스토리지를 활용하면 간단하게 Persistency 관리도 수행할 수 있습니다.