React Hooks 도입 고민과 첫 적용기
배경
회사 프로젝트는 여전히 Class Component 위주로 작성되어 있다. HOC와 render props 패턴이 중첩되면서 코드 가독성이 떨어지는 부분들이 생겼고, Hooks 도입을 검토하게 됐다.
첫 적용: 간단한 폼 상태 관리
기존 Class Component로 작성된 검색 폼을 Function Component + Hooks로 리팩토링했다.
// Before
class SearchForm extends React.Component {
state = { query: '' };
handleChange = (e) => {
this.setState({ query: e.target.value });
}
render() {
return <input value={this.state.query} onChange={this.handleChange} />;
}
}
// After
function SearchForm() {
const [query, setQuery] = useState('');
return <input value={query} onChange={(e) => setQuery(e.target.value)} />;
}
코드량이 확실히 줄었고, this 바인딩 고민이 사라졌다.
useEffect로 API 호출 처리
검색어 변경 시 디바운싱 후 API 호출하는 로직을 useEffect로 구현했다.
function SearchForm() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
useEffect(() => {
if (!query) return;
const timer = setTimeout(() => {
fetch(`/api/search?q=${query}`)
.then(res => res.json())
.then(setResults);
}, 300);
return () => clearTimeout(timer);
}, [query]);
return (/* ... */);
}
componentDidMount, componentDidUpdate를 분리해서 작성하던 것보다 직관적이다.
주의점
- 의존성 배열 관리가 생각보다 까다롭다. ESLint 플러그인 필수
- 팀원들이 Class Component에 익숙해서 학습 곡선 존재
- 기존 코드 전면 리팩토링보다는 신규 컴포넌트부터 적용 중
정리
당분간 Class와 Hooks를 혼용하면서 점진적으로 전환할 계획이다. 작은 컴포넌트부터 시작하니 리스크가 적고, 팀 내 학습 효과도 있었다.