React Hooks 프로젝트 도입 후기
배경
2월에 React 16.8이 정식 릴리즈되면서 Hooks가 stable로 올라왔다. 작년 말 발표 이후 관심은 있었지만 프로덕션에 적용하기엔 부담스러웠는데, 이번에 새로 시작하는 어드민 페이지에 적용해보기로 했다.
useState로 로컬 상태 관리
기존에는 간단한 토글 상태 하나 관리하려고 Class 컴포넌트로 만들어야 했다.
class Dropdown extends React.Component {
state = { isOpen: false };
toggle = () => {
this.setState({ isOpen: !this.state.isOpen });
}
render() {
return <div onClick={this.toggle}>...</div>;
}
}
Hooks를 사용하니 훨씬 간결해졌다.
function Dropdown() {
const [isOpen, setIsOpen] = useState(false);
return <div onClick={() => setIsOpen(!isOpen)}>...</div>;
}
useEffect의 혼란
componentDidMount, componentDidUpdate를 하나로 합친 useEffect의 개념이 처음엔 헷갈렸다. 특히 dependency array를 빈 배열로 넣으면 mount 시에만 실행되는 것, 특정 값을 넣으면 그 값이 변경될 때만 실행되는 것을 이해하는데 시행착오가 있었다.
useEffect(() => {
fetchUserData(userId);
}, [userId]); // userId 변경 시에만 재실행
Custom Hooks로 로직 분리
API 호출 로직을 custom hook으로 분리하니 재사용성이 크게 향상됐다.
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => {
setData(data);
setLoading(false);
});
}, [url]);
return { data, loading };
}
결론
아직 레거시 코드가 많아 전면 전환은 어렵지만, 새로 작성하는 컴포넌트는 Hooks로 가는 게 맞다고 판단했다. 보일러플레이트가 줄어들고 로직 재사용이 쉬워진 점이 체감된다. 다만 팀원들이 적응하는데 시간이 필요할 것 같다.