순수성
- 컴포넌트 렌더링 중에는 기존 변수나 객체를 절대 변경해서는 안 된다.
= 순수성을 지켜야 함
리액트가 순수성을 중시하는 이유
- 동일 입력에 대해 동일 결과를 반환하면 하나의 컴포넌트가 많은 사용자의 요청 처리 가능
- 입력 값에 변경이 없는 컴포넌트의 렌더링을 React.memo와 같은 메모이제이션으로 건너뛸 수 있어 성능을 향상시킬 수 있음
(순수 함수는 항상 동일한 결과를 반환하기 때문에 캐싱을 해도 안전)
- 컴포넌트 tree가 깊은 것을 렌더링하는 중에라도 데이터(state)가 바뀌면 리액트는 이전 렌더링을 완료하는 데 시간을 쓰지 않고 전체 렌더링을 바로 다시 시작
(순수성 덕분에 언제든지 계산을 중단해도 안전)
StrictMode
- 리액트는 개발 환경(development mode)에서 각 컴포넌트의 함수를 2번씩 호출하는 Strict Mode를 제공
- 컴포넌트 함수가 순수한 지(= 동일한 입력 값에 동일한 출력 값을 내놓는지) 확인하기 위해
- 즉, 1번째와 2번째 호출 때 각각 출력 값이 똑같은 지 확인하기 위해
- Strict Mode는 개발 환경에서만 작동하고 배포 환경(Production Mode)에서는 아무 영향을 미치지 않음
= Strict Mode로 인해 실 사용자의 앱 사용 속도가 느려지지 않음
사용법
- 리액트의 최상단 root 컴포넌트를
<React.StrictMode>
로 감싼다.
이벤트 핸들러 - 사이드 이펙트
- 함수형 프로그래밍은 순수성에 의존한다.
- 하지만 앱이 실행되다 보면 언젠가는 상태가 바뀌어야 함
- 화면 UI 변경, 애니메이션 작동, state 변경 등
=> 이러한 변화들은 렌더링 중이 아닌 렌더링 '후'에 부수적으로 일어나는 사이드 이펙트
- 리액트의 사이드 이펙트는 보통 이벤트 핸들러
- 렌더링이 완료된 화면에서 사용자의 동작에 따라 이벤트가 발생하는 것
- 이벤트 핸들러는 컴포넌트 함수 내부에 정의되어 있긴 하지만 무조건 렌더링 이후에 작동하므로 다른 요소들과 달리 순수할 필요가 없다.
이벤트 핸들러는 '호출'이 아니라 '전달'되어야
// handleClick 함수를 onClick 이벤트 핸들러로 '전달'
<button onClick={handleClick}> (O)
// handleClick 함수를 onClick 이벤트 핸들러에서 '호출'
<button onClick={handleClick()}> (X)
- handleClick 옆에 붙은 소괄호('()')는 렌더링 후의 사용자 클릭 이벤트를 기다리지 않고 JSX가 렌더링될 때 함수를 즉시 실행
// `handleClick` 함수가 `() => alert('...')`와 같다고 한다면
// 함수명이 아닌 함수 몸체 자체(=> 익명 함수)를 onClick에 전달한 모습
<button onClick={() => alert('...')}> (O)
// 인자가 들어가는 소괄호 없이 전달하면 함수 몸체의 일부만 전달한 것이나 다름없음
<button onClick={alert('...')}> (X)