-
Notifications
You must be signed in to change notification settings - Fork 4
리액트 렌더링 최적화
- ✍️ writer: 양예진
- 📆 date: 2020.11.11
- 성능 최적화를 할 때 필요한 useMemo, useCallback, React.Memo에 대해 알아본다.
-
리액트 컴포넌트는 기본적으로 부모 컴포넌트가 리렌더링되면 자식 컴포넌트 또한 리렌더링 된다.
바뀐 내용이 없을지라도 리렌더링된다. 컴포넌트 최적화를 하면 기존의 내용을 그대로 사용할 수 있다.
- 성능 최적화를 위하여
useMemo
라는 훅을 사용하여 연산된 값을 재사용한다. - useMemo는
특정 결과값
을 재사용할 때 사용한다.
- 첫 번째 파라미터:
어떻게 연산할지 정의하는 함수
- 두 번째 파라미터 : deps 배열을 넣어준다.
deps안에 있는 내용이 바뀌면, 함수를 호출하여 값을 연산하고, 내용이 바뀌지 않는다면 이전에 연산한 값을 재사용하게 된다.
const count = useMemo(() => countActiveUsers(users), [users]);
- useCallback은
특정 함수
를 새로 만들지 않고 재사용하고 싶을 때 사용한다.
-
함수를 선언하는 것 자체는 메모리도, CPU도 리소스를 많이 차지하는 작업은 아니다. 따라서 함수를 선언한다고 해서 그 자체만으로 큰 부하가 생기진 않지만, 한 번 만든 함수를 필요할 때만 새로 만들고 재사용하는 것은 여전히 중요하다.
그 이유는, 컴포넌트에서
props
가 바뀌지 않았으면 Virtual DOM에서 컴포넌트 결과물을 재사용하는 최적화를 한다. 이 작업을 하려면 함수 재사용하는 것이 필수적이다.
-
첫 번째 인자: 사용할 함수
-
두 번째 인자: 함수 안에서 사용하는 상태, props의 배열
const onCreate = useCallback(() => { const user = { id: nextId.current, username, email }; setUsers(users.concat(user)); setInputs({ username: '', email: '' }); nextId.current += 1; }, [users, username, email]);
-
컴포넌트의 props가 안바뀌었을 경우, 컴포넌트 리렌더링을 방지해준다.
-
컴포넌트에서 리렌더링이 필요한 상황에서만 리렌더링을 하도록 설정할 수 있다.
-
렌더링 최적화하지 않을 component에 React.memo를 사용하면, 불필요한 props만 비교하게 된다.
따라서 실제로 리렌더링을 방지할 수 있는 상황에서만 사용해야 한다.
- 최적화를 시켜줄 컴포넌트를 React.memo로 감싸준다.
function CreateUser({ username, email, onChange, onCreate }) {
return (
<div>
<input
name="username"
placeholder="계정명"
onChange={onChange}
value={username}
/>
...
<button onClick={onCreate}>등록</button>
</div>
);
}
export default React.memo(CreateUser);
-
콜백 함수의 파라미터에서 가장 최근의 state를 참조하게한다.
-
deps로 의존하는 값으로 state를 받아야할 때, 함수형 업데이트를 하여 콜백의 인자로 state를 준다.
이렇게 하면, deps에 State를 넣지 않아도 된다. ⇒ state가 바뀔 때, 리렌더링되지 않는다!
setState(prevState => prevState + 1);
// 함수형 업데이트 적용 안했을 시, deps에 state를 넣어야 한다.
const onToggle = useCallback(id => {
setUsers(
users.map(user =>
user.id === id ? { ...user, active: !user.active } : user
)
);
}, [users]);
// 함수형 업데이트
const onToggle = useCallback(id => {
setUsers(users =>
users.map(user =>
user.id === id ? { ...user, active: !user.active } : user
)
);
}, []);
- Reference
1️⃣ Week1
목표
데일리스크럼
회의
회고
2️⃣ Week2
목표
데일리스크럼
회의
회고
2️⃣ Week3
목표
데일리스크럼
회의
회고