컴포넌트를 엄격하게 순수함수로 작성하면 예상밖의 동작이나 당황케하는 버그를 피할 수 있다.
💡 순수성: 공식으로서의 컴포넌트
순수함수의 특징
- 함수 밖 객체나 변수를 변경하지 않음
- 같은 입력엔 항상 같은 결과를 반환함
React는 작성되는 모든 컴포넌트가 순수 함수일 거라 가정하고 설계되었다.
=>React 컴포넌트에 같은 입력이 주어지면 같은 JSX를 반환
💡 사이드 이펙트: 의도하지 않은 결과
React의 렌더링 과정은 항상 순수해야 한다. 컴포넌트는 렌더링하기 전에 존재했던 객체나 변수들을 변경하지 말아야 한다.
ex)
let guest = 0;
function Cup() {
// 나쁜 지점: 이미 존재했던 변수를 변경하고 있다!
guest = guest + 1;
return <h2>Tea cup for guest #{guest}</h2>;
}
export default function TeaSet() {
return (
<>
<Cup />
<Cup />
<Cup />
</>
);
}
위 컴포넌트가 여러번 불리면 다른 JSX를 생성하게됨..
다른 컴포넌트가 guest를 읽었다면 언제 렌더링 됐는지에 따라 그 컴포넌트 또한 다른 JSX를 생성..
예측할 수 없게 됨..
이는 guest 변수를 prop으로 넘겨 해결 가능
function Cup({ guest }) {
return <h2>Tea cup for guest #{guest}</h2>;
}
export default function TeaSet() {
return (
<>
<Cup guest={1} />
<Cup guest={2} />
<Cup guest={3} />
</>
);
}
이제 JSX가 반환되는 것은 오직 guest 프로퍼티에 의존하기 때문에 컴포넌트는 순수하다.
💡 Strict mode로 순수하지 않은 연산을 감지
- React에는 렌더링하면서 읽을 수 있는 props, state, context라는 세 가지 종류의 입력 요소가 있는데, 이 요소들은 항상 읽기 전용으로 취급해야 한다.
입력에 따라 무언가를 변경하려는 경우엔 변수를 직접 수정하는 대신 setState를 사용해야 한다. - React는 개발 중에 각 컴포넌트의 함수를 두 번 호출하는 “strict mode”를 제공
컴포넌트 함수를 두 번 호출함으로써, 엄격 모드는 이러한 규칙을 위반하는 컴포넌트를 찾는 걸 도와준다. - strict mode는 프로덕션에 영향을 주지 않기 때문에 사용자의 앱 속도가 느려지지 않는다. 최상단 컴포넌트를 <React.StrictMode>로 감싸서 stric mode 사용
💡 지역 변형
- 위에서 문제됐던 것은 렌더링하는 동안 컴포넌트가 "기존 변수"를 변경했다는 것.
렌더링하는 도중에 컴포넌트 내부에서 그냥 만든 변수와 객체를 변경하는 것은 문제가 없다.=> 지역 변형
💡 부작용을 일으킬 수 있는 지점
- 렌더링 중에 발생하는 것이 아니라 "사이드에서" 발생하는 현상을 사이드 이펙트라고 한다. (화면을 업데이트하고, 애니메이션을 시작하고, 데이터를 변경하는 등)
- 리액트에서 사이드 이펙트는 보통 이벤트 핸들러에 포함.
이벤트 핸들러는 리액트가 일부 작업을 수행할 때 반응하는 기능, 컴포넌트 내부에 정의되었다 해도 렌더링 중에는 실행되지 않음 -> 이벤트 핸들러는 순수할 필요가 없음! - 사이드 이펙트에 적합한 이벤트 핸들러를 찾을 수 없는 경우 : useEffect 호출을 사용하여 JSX에 해당 이벤트 핸들러를 연결할 수 있으나 이 방법은 최후의 수단으로 사용하자
- 👉 가능하면 렌더링만으로 로직을 표현하기.
리액트는 why 순수해야될까?
- 동일한 입력에 대해 동일한 결과를 반환하기 때문에 하나의 컴포넌트는 많은 사용자 요청을 처리할 수 있다.
- 입력이 변경되지 않은 컴포넌트는 렌더링을 건너뛰어 성능을 향상시킬 수 있다.
- 깊은 컴포넌트 트리를 렌더링하는 도중에 일부 데이터가 변경되는 경우 React는 오래된 렌더링을 완료하는 데 시간을 낭비하지 않고 렌더링을 다시 시작할 수 있다.
'3주차' 카테고리의 다른 글
React에서의 '상태관리' 😎 (0) | 2024.11.02 |
---|---|
[React] useState와 useReducer의 차이점 (0) | 2024.11.02 |
명령형 프로그래밍과 선언형 프로그래밍 (0) | 2024.11.02 |
React에서 중복 로직을 해결하는 법 (0) | 2024.11.02 |
[React] children prop과 친해지자 (0) | 2024.11.02 |