
react 스터디에서 리액트를 다루는 기술이라는 책을 선정했고 이 책을 읽고 배운 것을 바탕으로 작성되었다.
React Developer Tools 설치Profiler 탭 분석❗ 주로 업데이트가 발생한 컴포넌트랑 관계없는 컴포넌트들도 리렌더링 되는 문제 발생
컴포넌트는 다음과 같은 상황에서 리렌더링이 발생함
props가 변경될 때state가 바뀔 때forceUpdate함수가 실행될 때❗ 불필요한 리렌더링이 발생하지 않도록 해야 한다.
life cycle method 중 shouldComponentUpdate 사용하면 된다.React.memo라는 함수를 사용한다.props가 바뀌지 않았다면 리렌더링하지 않도록 하여 컴포넌트의 리렌더링 성능을 최적화할 수 있다.export default React.memo(MyComponent);
useCallback을 이용하여 특정 함수가 리렌더링마다 새로 생성되지 않고 재사용할 수 있도록 하지만, useCallback과 더불어 useState의 함수형 업데이트를 이용하여 함수 생성 횟수를 더욱 더 줄여 리렌더링 성능을 최적화할 수 있다.const [number, setNumber] = useState(0);
// Before: number 상태 값이 바뀔 때 마다 등록된 함수가 새로 생성됨.
const onIncrese = useCallback(
() => setState(number + 1);,
[number]
);
// After
const onIncrease = useCallback(
() => setState(prevNumber => prevNumber + 1);,
[]
);
setState함수에 함수인자를 넣으면 그 함수는 이전 상태값을 인자로 받아 참조하여 상태값을 업데이트시킬 수 있다.useCallback의 두번째 인자로 빈 배열을 넣어 초기렌더링 시에만 함수를 생성하고 리렌더링될 때마다 처음에 생성된 함수를 재사용하도록 한다.function reducer(state, action){
switch(action.type){
case "INCREMENT":
return { number : state.number + 1};
default:
return state;
}
}
...
const [state, dispatch] = useReducer(reducer, { number : 0 });
const onIncrese = useCallback(
dispatch({ type: "INCREMENT" });,
[]
);
useReducer의 장점은 컴포넌트의 state 업데이트 로직을 바깥으로 빼낼 수 있다는 것이다.reducer 함수는 첫번째 인자로 항상 현재 상태값을 가져오기 때문에 컴포넌트 내부에서는 dispatch함수를 이용하여 action 인자를 받아 reducer함수를 호출하면 된다.useCallback으로 등록된 함수 내부에서는 현재 상태값에 의존하지 않아도 되므로 두 번째 인자로 빈 배열을 전달하여 초기 렌더링 시 생성된 함수를 리렌더링될 때마다 재사용할 수 있도록 한다.react-virtualized 라이브러리를 이용하면 스크롤되기 전에 보이지 않는 컴포넌트는 렌더링하지 않고 크기만 차지하게끔 할 수 있다.useMemo와 useCallback은 주로 컴포넌트 성능을 최적화하기 위해 사용된다.trade-off가 존재한다. 퍼포먼스를 최적화시켰지만, 컴퓨터 자원 등 소모되는 자원이 있다.useMemo와 useCallback을 이용하면 컴포넌트 성능을 최적화할 수 있지만 의존성 배열의 값을 관리하고 메모이제이션을 위해 메모리를 소모해야 한다. 어쩌면 이득보다 더 큰 대가를 치러야 할 수 있다.Referential Equality책임감 있게 최적화해야 한다 ❗
적재적소에 사용하자 ❗