Fragement
와 같이 UI를 렌더링하지 않으며, 자손들에 대한 부가적인 검사와 경고를 활성화함strictMode
를 활성화할 수 있음import React from 'react';
function ExampleApplication() {
return (
<div>
<Header />
<React.StrictMode>
<div>
<ComponentOne />
<ComponentTwo />
</div>
</React.StrictMode>
<Footer />
</div>
);
}
StrictMode
검사가 이루어지지 않지만, ComponentOne과 ComponentTwo 컴포넌트는 각각 자손까지 StrictMode
검사가 이루어짐StrictMode
가 검사하는 항목들불안전한 코드 실행을 유발하는 생명주기 메서드가 존재함
componentWillMount
componentWillReceiveProps
componentWillUpdate
이 생명주기 메서드들은 잘못 이해하고 잘못 사용하기 쉬우며, 비동기 렌더링과 함께 잘못 사용할 경우 문제가 될 수 있음
애플리케이션이 3rd party 라이브러리를 사용한다면, 해당 생명주기 메서드가 사용되지 않는다고 장담하기 어려움
StrictMode
가 도움이 됨StrictMode
가 활성화되면, React는 안전하지 않은 생명주기 메서드를 사용하는 모든 클래스 컴포넌트 목록들 정리하여 컴포넌트에 대한 정보가 담긴 긴 경고 로그를 출력함StrictMode
에 의해 발견된 문제를 해결한다면, 향후 릴리즈되는 React에서 동시 발생하는(concurrent) 렌더링의 이점을 얻을 수 있음Concurrent Mode
문제점 1 : 기존의 debounce와 throttle은 한계점이 존재함
concurrent mode
는 debounce와 throttle의 한계점을 동시성으로 해결함
문제점 2 : 렌더링이 충분히 빠름에도 의미 없는 로딩을 보여주는 경우가 존재함
concurrent mode
는 일정 시간 동안 현재 페이지와 기능들을 유지하고, 다음 페이지에 대한 렌더링을 동시에 진행함으로써 해결함
- 그리고 다음페이지의 렌더링 단계가 특정 조건에 부합하면, 해당 페이지를 렌더링함
- 특정 state 변경에 대한 현 화면의 UI 렌더링 단계보다 더 최신 단계로 진행하여야 실제 DOM에 반영함
createRef
API가 도입되면서 객체 ref를 사용할 수 있게 됨createRef
API와 별개로 콜백 API는 계속 지원됨class MyComponent extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
render() {
return <input type="text" ref={this.inputRef} />;
}
componentDidMount() {
this.inputRef.current.focus();
}
}
StrictMode
는 문자열 ref의 사용에 대해 경고함이전의 React에서는 주어진 클래스 인스턴스를 바탕으로 트리를 탐색해 DOM노드를 찾을 수 있는 findDOMNode
를 지원했음
findDOMNode
는 클래스 컴포넌트에서 사용할 수 있지만, 부모가 특정 자식을 렌더링하도록 허락하기 때문에 추상화 레벨이 무너짐findDOMNode
는 일회용, 읽기 전용 API이기 때문에, API를 호출했을 때만 값을 반환함findDOMNode
는 항상 변하지 않는 단일 DOM 노드를 반환하는 컴포넌트에서만 정상적으로 작동함이제는 DOM노드에 바로 ref를 지정할 수 있으므로, 보통 findDOMNode
가 필요하지 않음
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.wrapper = React.createRef();
}
render() {
return <div ref={this.wrapper}>{this.props.children}</div>;
}
}
React는 개념적으로 두 단계로 동작함
render
를 호출하여 이전 렌더링 결과와 현재 렌더링 결과를 비교함componentDidMount
나 componentDidUptate
와 같은 생명주기 메서드를 호출함커밋 단계는 일반적으로 매우 빠르지만, 렌더링 단계는 느릴 수 있음
렌더링 단계의 생명주기 메서드는 다음과 같음
constrcutor
componentWillMount
(or UNSAFE_componentWillMount
)componentWillReceiveProps
(or UNSAFE_componetWillReceiveProps
)componentWillUpdate
(or UNSAFE_componetWillUpdate
)getDerivedStateFromProps
shouldComponentUpdate
render
setState
업데이트 함수 (첫 번째 인자)위 메서드들은 여러번 호출될 수 있기 때문에, 메서드에 side-effect를 포함하지 않는 것이 중요함
StrictMode
가 자동으로 side effect를 찾아주는 것은 불가능하지만, side effect를 예측할 수 있게 만들어서 문제되는 부분을 발견할 수 있게 도와줌StrictMode
는 아래의 함수들을 고의적으로 2번 호출함을 통해서 문제되는 부분을 발견함constructor
, render
, shouldComponentUpdate
getDrivedStateFromProps
useState
, useMemo
, useReducer
에 전달되는 함수
- development mode에서만 위 메서드들이 2번 호출됨 (production mode에서는 그렇지 않음)
class TopLevelRoute extends React.Component {
constructor(props) {
super(props);
SharedApplicationState.recordEvent('ExampleComponent');
}
}
StrictMode
는 컴포넌트의 constructor
와 같은 메서드를 의도적으로 2번 호출함으로써 이와 같은 패턴을 쉽게 찾을 수 있게 함StrictMode
에서는 아래와 같은 경고 메세지를 보여줌createContext
API를 사용해서 migration하는 것을 권장함미래에는 React가 상태를 유지하면서 UI section을 추가하고 삭제하는 기능을 추가할 예정임
이러한 문제를 해결하기 위해서, React 18은 StrictMode
에서의 새로운 development mode check를 도입함
StrictMode
의 새로운 check를 사용하지 않을 때, 컴포넌트가 마운트되었을 때, React가 생성하는 effect의 예시
- React가 컴포넌트를 마운트함
1-1. Layout effects가 생성됨
1-2. Effects가 생성됨
StrictMode
의 새로운 check를 사용할 때, 컴포넌트가 마운트되었을 때, React가 생성하는 effect의 예시
- React가 컴포넌트를 마운트함
1-1. Layout effects가 생성됨
1-2. Effects가 생성됨- React가 마운트되었던 컴포넌트의 effect를 삭제함
2-1. Layout effects가 삭제됨
2-2. Effects가 삭제됨- React가 다운드되었던 컴포넌트를 재생성함
3-1. Layout effects가 생성됨
3-2. Effect setup 코드가 실행됨
위 예시를 통해서 React는 두번째 마운트 때 첫 번째 마운트로부터의 상태를 회복시킨다는 것을 알 수 있음
컴포넌트의 마운트가 해제될 때, effect는 일반적으로 삭제됨
- React가 컴포넌트의 마운트를 해제함
1-1. Layout effects가 삭제됨
1-2. Effects가 삭제됨