const [state, dispatch] = useReducer(reducer, initialArg, init);
useState의 대체 함수, 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리할 수 있다. 상태 업데이트 로직을 컴포넌트 바깥으로 빼거나 다른 파일에 작성해 불러와서 사용 가능하다.
import React, { useState } from "react";
const Counter = () => {
const [count, setCount] = useState(0);
const handleIncrease = () => {
setCount(prevCount => (prevCount += 1));
};
const handleDecrease = () => {
setCount(prevCount => (prevCount -= 1));
};
return (
<>
<h1>{count}</h1>
<button onClick={handleIncrease}>+1</button>
<button onClick={handleDecrease}>-1</button>
</>
);
};
export default Counter;
}
import React, { useReducer } from "react";
const reducer = (state, action) => {
switch (action.type) {
case "INCREASE":
return { ...state, count: action.count };
case "DECREASE":
return { ...state, count: action.count };
default:
throw new Error(`Unhandled error : ${action.type}`);
}
};
const Counter = () => {
const [state, dispatch] = useReducer(reducer, {
count: 0
});
const { count } = state;
const handleIncrease = () => {
dispatch({ type: "INCREASE", count: count + 1 });
};
const handleDecrease = () => {
dispatch({ type: "DECREASE", count: count - 1 });
};
return (
<>
<h1>{count}</h1>
<button onClick={handleIncrease}>+1</button>
<button onClick={handleDecrease}>-1</button>
</>
);
};
export default Counter;
이런식으로 useState를 useReducer로 변경이 가능하다.
useState, useReducer를 상황에 맞게 잘 선택하는게 좋다.
state가 컴포넌트에 하나거나 단순한 값이라면 useState가 좋은 선택이고, 만약 컴포넌트에서 관리하는 값이 여러개 또는 상태의 구조가 복잡해지면 useReducer를 선택하는게 좋다.
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
props로 넘겨주는 함수는 useCallback이 필수이다. 그 이유는 함수형 컴포넌트는 state가 바뀔 때 마다 코드가 전체 재 실행이 된다. 즉 함수가 재 생성이 되는 것이다. 따라서 그 함수를 props로 받는 자식 컴포넌트들이 불필요한 렌더링이 발생하게 되는 것이다.
useCallback은 이러한 불필요한 렌더링을 방지하기 위해 메모이제이션이된 콜백을 반환한다. deps 값을 배열에 넣어 전달한다.콜백함수의 메모이제이션된 버전을 반환하고 그 메모이제이션된 버전은 콜백의 deps에 넣어 준 값이 변경되었을 때에만 변경된다.
즉 불필요한 렌더링 방지를 위해 참조의 동일성에 의존적인 최적화된 자식 컴포넌트에 콜백을 전달할 때 유용하게 쓰인다.
useCallback(fn, deps)은 useMemo(() => fn, deps)와 같다.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
메모이제이션된 값을 반환한다. 위의 useCallback과 같이 deps 배열에 의존성 값을 넣어준다.
의존성이 변경되었을 때에만 메모이제이션된 값만 다시 계산을 한다. 물론 useMemo도 성능 최적화를 위한 방법이다.
const refContainer = useRef(initialValue);
- 외부 라이브러리를 사용하여 만들어진 인스턴스
- setTimeout, setInterval을 통해서 만들어진 id
- 엘리먼트의 크기 가져오기
- 스크롤바 위치 가져오기
- 포커스 설정 등...