React.js Hooks 완벽 가이드: useState, useEffect 활용법
React.js Hooks 완벽 가이드: useState, useEffect 활용법
React는 사용자 인터페이스를 구축하기 위한 강력하고 유연한 라이브러리입니다. React에서 컴포넌트 상태를 관리하고 생명 주기 이벤트를 처리하기 위해 필요한 것이 Hooks
입니다. 이 글에서는 가장 널리 사용되는 두 가지 Hook인 useState
와 useEffect
의 기본 개념과 활용 방법을 다루고자 합니다. 앞서 나가기에 앞서, Hooks는 함수형 컴포넌트에서 사용할 수 있습니다.
useState: 상태 관리를 위한 Hook
useState
는 리액트 컴포넌트에서 상태를 관리할 때 사용하는 Hook입니다. 클래스형 컴포넌트에서는 this.state
와 this.setState
를 사용했지만, 함수형 컴포넌트에서는 useState
를 통해 상태를 설정하고 업데이트합니다. 다음은 기본적인 사용 예제입니다.
javascriptimport React, { useState } from 'react'; function Counter() { // count라는 상태 변수와 setCount라는 상태 업데이트 함수를 선언합니다. const [count, setCount] = useState(0); return ( <div> <p>현재 카운트: {count}</p> <button onClick={() => setCount(count + 1)}>증가</button> </div> ); }
위 예제에서 useState(0)
는 초기 상태 값을 0으로 설정합니다. useState
는 두 개의 값을 반환하는데, 첫 번째 값은 현재 상태, 두 번째 값은 상태를 갱신할 수 있는 함수입니다. 상태를 갱신하기 위해서는 그 함수에 새로운 상태 값을 넘겨주면 됩니다.
상태를 여러 개 설정하기
복잡한 상태를 관리하기 위해 useState
를 여러 번 호출할 수 있습니다. 예제는 다음과 같습니다.
javascriptfunction Profile() { const [name, setName] = useState(''); const [age, setAge] = useState(0); return ( <div> <input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder="이름을 입력하세요" /> <input type="number" value={age} onChange={(e) => setAge(Number(e.target.value))} placeholder="나이를 입력하세요" /> <p>이름: {name}</p> <p>나이: {age}</p> </div> ); }
위 코드에서 우리는 name
과 age
두 개의 상태 변수를 설정하고 이를 각각의 입력 필드와 연결하였습니다. 상태 업데이트는 입력값의 변화에 따라 이루어집니다.
useEffect: 사이드 이펙트를 처리하는 Hook
useEffect
는 컴포넌트가 렌더링된 이후에 특정 작업을 수행하기 위해 사용하는 Hook입니다. 클래스형 컴포넌트의 componentDidMount
, componentDidUpdate
, componentWillUnmount
와 비슷한 역할을 합니다. 다음은 기본적인 사용 예제입니다.
javascriptimport React, { useState, useEffect } from 'react'; function Timer() { const [seconds, setSeconds] = useState(0); useEffect(() => { const interval = setInterval(() => { setSeconds((prevSeconds) => prevSeconds + 1); }, 1000); // 컴포넌트가 언마운트될 때 인터벌을 정리합니다. return () => clearInterval(interval); }, []); // 빈 배열은 의존성을 의미하며, 이 경우 컴포넌트가 처음 마운트될 때 한 번만 실행됩니다. return ( <div> <p>타이머: {seconds} 초</p> </div> ); }
위 예제에서 useEffect
는 인터벌을 설정하고 컴포넌트가 언마운트될 때 인터벌을 정리합니다. useEffect
의 두 번째 인자로 빈 배열을 제공하면, 이 효과는 컴포넌트가 처음 렌더링될 때 한 번만 실행됩니다.
여러 종류의 사이드 이펙트 관리하기
useEffect
를 여러 번 호출하여 다양한 사이드 이펙트를 관리할 수 있습니다. 예를 들어, API 호출과 정리 작업을 각각 분리할 수 있습니다.
javascriptimport React, { useState, useEffect } from 'react'; function DataFetcher({ apiEndpoint }) { const [data, setData] = useState(null); const [error, setError] = useState(null); // 데이터 가져오기 useEffect(() => { fetch(apiEndpoint) .then(response => response.json()) .then(data => setData(data)) .catch(error => setError(error)); }, [apiEndpoint]); // apiEndpoint가 바뀔 때마다 이 효과 실행 // 정리 작업 useEffect(() => { return () => { console.log('컴포넌트 언마운트됨'); }; }, []); if (error) return <div>에러 발생: {error.message}</div>; if (!data) return <div>로딩 중...</div>; return ( <div> <pre>{JSON.stringify(data, null, 2)}</pre> </div> ); }
위 예제에서 첫 번째 useEffect
는 API 엔드포인트가 변경될 때마다 데이터를 다시 로드합니다. 두 번째 useEffect
는 컴포넌트가 언마운트될 때 정리 작업(이 경우 단순히 콘솔 로그)을 수행합니다.
결론
useState
와 useEffect
는 리액트가 클래스형 컴포넌트의 복잡함을 줄이고 함수형 컴포넌트만으로도 충분히 복잡한 상태와 사이드 이펙트를 관리할 수 있도록 하는 강력한 도구입니다. 이 두 Hook의 적용 범위는 매우 넓으며, 리액트 애플리케이션을 더욱 효율적으로 만들기 위해 반드시 익혀야 할 기본 요소입니다.