Hook 사용시 함수 컴포넌트에서 state(상태)와 생명주기를 할 수 있게됩니다.
useState는 함수 컴포넌트에서 상태(state)를 관리하기 위해 사용하는 훅(hook)입니다.
리액트에서는 변수의 값이 변경되어도 화면이 자동으로 리렌더링되지 않습니다.
따라서 값을 상태로 관리하고, 변경할 때는 useState를 통해 업데이트해야 화면에 반영됩니다.
const [state, setState] = useState(initialState)
useState를 효율적으로 사용하여 애플리케이션의 성능을 향상시키는 방법을 알아봅시다.
setUser(prev => ({ ...prev, name: 'June' }));
이전 state를 안전하게 유지하면서 필요한 부분만 변경할 수 있습니다.
const heavy() => {
return [1, 2];
}
const [number, setNumber] = useState(() => heavy());
초기값이 무거운 경우, 콜백 함수를 사용하여 최초 렌더링 시에만 실행되도록 최적화할 수 있습니다.
useEffect는 특정 시점에 원하는 작업을 수행할 수 있게 해주는 Hook입니다.
컴포넌트의 마운트, 업데이트, 언마운트 시점에 특정 코드를 실행할 때 유용하게 사용됩니다.
useEffect를 사용할 때 2가지 방식이 있습니다.
// 1. 기본 문법
useEffect( () => {작업} );
가장 기본적인 형태로, 콜백 함수를 인자로 받아, 컴포넌트가 렌더링될 때마다 실행됩니다.
// 2. 의존성 배열 사용
useEffect( () => {작업}, [의존성] );
두 번째 인자로 의존성 배열을 넣으면, 콜백 함수는 처음 렌더링될 때, 배열 안 값이 바뀔 때만 다시 실행됩니다. 만약 배열이 비어 있다면, 마운트 시에 한 번만 실행됩니다.
useEffect에서 함수를 반환하면, 이 함수는 '클린업(정리) 함수'로 동작합니다.
useEffect( () => {
작업
return () => {
작업 해제
}
}, [의존성] );
클린업 함수는 컴포넌트가 언마운트(제거)될 때, 의존성이 변경되어 effect가 다시 실행되기 전에 정리 작업을 수행합니다.
클린업 함수는 React 애플리케이션의 성능 최적화와 깊은 관련이 있습니다:
메모리 누수 방지: 이벤트 리스너, 타이머, 구독 등을 정리하지 않으면 컴포넌트가 사라질 때 메모리 누수가 발생할 수 있습니다.
불필요한 동작 방지: 이전 effect의 영향이 새로운 effect에 간섭하는 것을 방지합니다.
변수를 저장하고 관리할 수 있는 Hook입니다.
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
}, []);
return <input ref={inputRef} />;
useRef는 current 속성을 가진 변경 가능한 객체를 반환합니다.
useRef로 생성된 객체는 컴포넌트의 전체 생애주기 동안 유지됩니다.
1. DOM 요소에 접근
2.렌더링 여부
useState의 값이 변경되면 컴포넌트가 다시 렌더링됩니다.
useRef의 값이 변경되어도 컴포넌트가 렌더링되지 않습니다.
컴포넌트가 리렌더링되어도 useRef의 값은 유지됩니다.
useContext는 전역 데이터를 간편하게 가져올 수 있도록 해주는 Hook입니다.
const ThemeContext = createContext('light');
const App = () => {
const [isDark, setIsDark] = useState(false);
return (
<ThemeContext.Provider value={{ isDark, setIsDark }}>
<Page />
</ThemeContext.Provider>
);
};
const Page = () => {
const { isDark } = useContext(ThemeContext);
return <div>{isDark ? 'Dark Mode' : 'Light Mode'}</div>;
};
1. 전달 방식
Props : 부모에서 자식으로 직접 데이터를 전달합니다.
Context : 컴포넌트 트리 안의 어떤 컴포넌트든 필요한 곳에서 데이터를 바로 사용할 수 있습니다.
2. 사용 목적
Props : 개별 컴포넌트 간 명확한 데이터 전달에 적합합니다.
Context : 테마, 사용자 정보, 언어 설정 등 전역 상태를 여러 컴포넌트에서 공유할 때 유용합니다.
useMemo는 리렌더링 사이에 계산 결과 값을 캐싱해 주는 Hook입니다.
const cachedValue = useMemo(value, [의존성])
함수형 컴포넌트는 렌더링될 때마다 내부 변수와 함수가 새로 실행됩니다.
useMemo는 결과값을 기억해서, 의존성 배열의 값이 바뀌지 않는 한 재계산을 건너뜁니다.
1. 불필요한 사용 줄이기
useMemo는 메모리를 사용해서 값을 캐싱하므로, 단순한 값이나 가벼운 계산에는 오히려 성능이 나빠질 수 있습니다.
꼭 무거운 연산이거나 렌더링마다 다시 계산되면 문제가 되는 경우에만 사용해야 합니다.
2. 상태 관리 도구가 아닙니다.
useMemo는 값을 저장하는 목적이 아니라, 계산 비용을 줄이기 위한 최적화 도구입니다.
상태를 유지하거나 공유하려면 useState나 useContext 같은 전용 훅을 사용해야 합니다.
useCallback은 리렌더링 간에 함수 정의를 캐싱해 주는 Hook입니다.
const cachedFn = useCallback(fn, [의존성])
함수형 컴포넌트는 렌더링될 때마다 내부 변수와 함수가 새로 실행됩니다.
useCallback은 함수 정의를 기억해서, 의존성 배열의 값이 바뀌지 않는 한 재계산을 건너뜁니다.
useReducer는 컴포넌트에 reducer를 추가하는 Hook입니다.
const [state, dispatch] = useReducer(reducer, initialState);
useReducer는 다음 세 가지 핵심 요소로 구성됩니다
Dispatch : action을 발생시키는 함수입니다. action을 reducer에 전달하여 상태를 변경합니다.
Action : 상태를 어떻게 바꿀지를 설명하는 객체입니다. 일반적으로 type과 payload를 포함합니다.
Reducer : 상태를 업데이트하는 함수입니다. 현재 상태와 action을 받아서 새로운 상태를 반환합니다.
1. 사용 목적
useState : 간단한 상태 관리에 적합합니다.useReducer : 복잡한 상태 로직 관리에 적합합니다.2. 상태 업데이트 방식
useState : 직접 상태를 설정합니다.useReducer: reducer 함수에서 상태를 계산합니다.React를 사용하다 보면 비슷한 로직을 여러 컴포넌트에서 반복하게 되는 일이 많습니다. 이런 반복 코드를 줄이고 재사용성을 높이기 위해, 나만의 Hook(Custom Hook)을 만들어 사용할 수 있습니다.
// 커스텀 훅 생성
function useWindowWidth() {
//작업
}
export default useWindowWidth;
// 커스텀 훅 사용
import useWindowWidth from "./useWindowWidth";
function MyComponent() {
const width = useWindowWidth();
return <p>너비는 {width}px 입니다.</p>;
}
커스텀 훅의 이름은 "use"로 시작하기.
일관성, 식별성, 자동 검사 기능이 제대로 작동하도록 하기 위해 반드시 "use"로 시작해야 합니다.
이 네이밍 규칙을 따르지 않으면 ESLint가 훅 규칙 위반을 감지하지 못하고, 이로 인해 예기치 않은 버그가 발생할 수 있습니다.