
React Hook은 함수 컴포넌트에서 상태 관리와 생명주기 기능 등을 이용할 수 있도록 도와주는 함수!
React 생애주기: 컴포넌트가 렌더링되기 시작하고, 업데이트되고, 언마운트 되기까지의 일련의 과정
Mount(마운트, 첫 렌더링) → Update(리렌더링) → UnMount(화면에서 사라짐)
use- 로 시작use 라는 접두사를 이용하여 커스텀 훅(custom hook) 제작 가능대표적인 것들만 정리 해보고 최적화 관련 함수들은 다음에 정리해 볼 예정
상태 관리 hook
const [ state, setState] = useState(initialState);
// [새롭게 생성된 state값, state 상태 변경 함수] = useState(초기값)
생애 주기 관리 hook
useEffect(setup, dependencies?)
// useEffect(실행할 콜백 함수, 의존성 배열)
배열에 들어가 있는 값이 바뀌게 되면 첫 번째 인수로 전달한 콜백 함수를 실행
useEffect(() => {
// 모든 렌더링 후에 실행
});
useEffect(() => {
// 마운트될 때만 실행 (컴포넌트가 나타날 때)
}, []);
useEffect(() => {
// 마운트될 때 실행, 또한 렌더링 이후에 a 또는 b 중 하나라도 변경된 경우에도 실행됩니다
}, [a, b]);
useEffect 에서 반환된 함수를 클린업(cleanup) 함수라고 부른다
주로 컴포넌트가 언마운트 될 때, effect가 다시 실행되기 전에 이전 effect가 남긴 것을 정리하는 용도로 사용 (리소스 정리)
useEffect(() => {
const connection = createConnection(); // 컴포넌트가 마운트될 때 실행되는 작업
connection.connect();
// cleanup 함수
return () => {
connection.disconnect(); // 컴포넌트가 언마운트될 때 실행되는 작업
};
}, []);
✔️ 의존성 배열 설정 유의점
useEffect 내부에 사용하는 state나 props, 함수 등은 반드시 의존성 배열에 포함시켜야한다eslint-plugin-react-hooks 라는 플러그인으로 의존성 배열 누락 여부를 검사할 수 있음 (누락 시 effect가 이전 값을 참조하는 버그 알려줌)의존성 배열에 객체나 함수, 배열을 넣을 경우 원치 않은 무한 루프나 재실행을 유발하기 쉬우므로 주의하기
객체 및 함수는 다음에 정리할 useMemo나 useCallback 등으로 참조 유지하거나 useEffect 내부로 이동 추천
// ❌ 객체 전체를 전달하면 매 렌더링마다 새 참조라 매번 재실행될 수 있음
useEffect(() => {
fetchData(user.id);
}, [user]);
// ⭕ 필요한 값만 전달하여 불필요한 재 실행 방지
useEffect(() => {
fetchData(user.id);
}, [user.id]);
컴포넌트 내부 변수로 일반적인 값들을 저장할 수가 있음
렌더링에 필요하지 않은 값을 참조 → 보여주지 않을 변수 (렌더링 X)
const ref = useRef(initialValue)
// 참조(Reference) 객체 = useRef(초기값)
DOM 접근 가능 → state처럼 값은 유지하지만 변경되어도 리렌더링 안됨
const inputRef = useRef(null);
const focusInput = () => inputRef.current.focus();
return <input ref={inputRef} />;
컴포넌트간 데이터를 전달하는 방법으로
context는 데이터 객체(보관소)라고 보면 된다
보통 변하는 값과, 변하지 않는 값을 구분하여 Context를 분리함
→ 하나의 Context에 다 넣으면 값 하나만 바뀌어도 구독하는 모든 컴포넌트가 리렌더링 되므로

const SomeContext = createContext(defaultValue) // 생성한 context
const value = useContext(SomeContext) // 호출하는 컴포넌트에 대한 context 값을 반환
const { someValue } = useContext(SomeContext) // 필요한 값만 가져올 수 있음
Context.Provider : Context에 포함된 값을 제공하는 컴포넌트
provider 아래의 모든 컴포넌트들은 해당 Context의 데이터를 공급받을 수 있음
<BoardContext.Provider>
<CreateForm onCreate={onCreate} />
<List onUpdate={onUpdate} onDelete={onDelete} boards={boards} />
</BoardContext.Provider>
컴포넌트 내부에 새로운 state를 생성하는 hook
모든 useState 는 useReducer 로 대체 가능
다른 점은, 상태 변경 로직을 컴포넌트 외부(reducer 함수)로 분리할 수 있다는 것
여러 세부 상태를 하나의 로직으로 묶어서 관리하기 좋음
const [state, dispatch] = useReducer(reducer, initialValue)
// [상태, 상태 변화가 있어야한다는 사실을 알리는 함수] = useReducer(상태를 실제로 변화시키는 변환기, 초기값)
흐름 : 이벤트 발생 → dispatch(action) 호출 → Reducer 실행 → 반환된 새 state로 업데이트
복잡한 구조는 보통 useReducer를 이용해서 관리하고 간단한 상태 변화 코드만 있다면 useState 를 이용
function reducer(state, action) {
switch (action.type) {
case "INCREASE":
return state + action.data;
case "DECREASE":
return state - action.data;
default:
return state;
}
}
export default function App() {
const [state, dispatch] = useReducer(reducer, initialValue);
const onClickPlus = () => {
dispatch({
type:"INCREASE", // 상태를 어떻게 변화시키길 원하는지
data: 1, // 어느정도 변화시킬지
})
}
}
Hooks의 종류
[React AtoZ] useEffect와 의존성 배열, 그리고 EsLint
React useEffect 의존성 배열: 객체 vs 구체적인 값
한 입 크기로 잘라 먹는 리액트