출처 : https://velog.io/@kysung95/%EC%A7%A4%EB%A7%89%EA%B8%80-react-strict-%EB%AA%A8%EB%93%9C%EB%9E%80
오늘은 react 개발 시에 strict모드가 무엇인지에 대해 설명드리고자 합니다.
오늘은 아주 짧게 개념만 설명드리도록 할께요!
strict 모드
예전에 react를 처음 접할 때에는 npx create-react-app 명령어를 통해서 react 프로젝트를 생성시키곤 했습니다. 현재는 저 명령어를 사용하지 않고, webpack을 이용해서 react 프로젝트를 만들고 실행하는데, npx 명령어를 사용하여 react 앱을 생성하면 자동으로 strict 모드라는 것이 설정된다는 것 혹시 알고계셨나요?
npx 명령어를 통해 react 프로젝트를 생성한 후 index.js 파일을 살펴보겠습니다.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
App 태그를 감싸고 있는 저 녀석, 저 녀석이 바로 react의 strict 모드입니다.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
이런 식으로 해당 strict 모드 태그를 삭제하고 프로젝트를 실행해도 별다른 문제가 생기지 않습니다.
그렇다면 저 strict는 어떤 것이고, 왜 있는걸까? strict 모드가 야기하는 현상에는 어떠한 것이 있는가에 대해 여러분들에게 설명드리겠습니다.
react의 공식 문서에서 살펴보면 strict 모드란 react 앱 내의 잠재적인 문제를 알아내기 위한 도구라고 나와있습니다.
우선 strict 모드는 개발 과정 중에만 적용이 됩니다. 배포가 되고나면 strict 모드는 저절로 작동하지 않기 때문에 걱정하지 않으셔도 됩니다! 그 점을 알아두시고 strict 모드의 기능에 대해 알아가시면 좋을 것 같네요.
안전하지 않은 것들에 대한 경고
리액트는 렌더링 단계와 커밋 단계 두가지의 단계로 동작합니다.
렌더링 단계는 render 함수를 호출해서 이전 렌더와 비교를 수행하는 단계이고, 커밋 단계의 경우에는 라이프 사이클 함수를 실행시키며 DOM 노드를 추가/변경해주는 단계입니다. 여기서 커밋단계는 일반적으로 렌더링 단계보다 빠릅니다.
그로인해 느린 렌더링 단계에서 여러 생명주기 메서드가 여러번 호출되기도 합니다. 이러한 것들을 strict 모드에서는 미리 파악하고 우리에게 경고해줍니다. 보통 class component의 생명 주기 메소드인 componentWillMount()나 componentWillUpdate() 등에서 이런 형태가 나타나지만 setState에서 역시 이러한 현상들이 나타납니다. 당연히 setState와 같은 기능으로 사용되는 useState에서도 이러한 현상이 나타나는 경우가 있습니다.
이러한 메서드들은 여러 번 호출될 수 있기 때문에 원하는 결과값을 보존하기 위해서 미리 잡아야 합니다. 그럴 때 우리가 Strict 모드를 통해 2번 수행되는 메서드들을 잡아 미리 고칠 수가 있는 것입니다. 물론 Strict 모드가 자동적으로 모든 부작용을 찾아낼 수는 없지만, 문제가 될 만한 함수를 두 번 실행하는 방법으로써 이러한 발견을 도와줍니다. 즉 Double-Invoke 방식을 통해 이를 우리에게 알려주는 것이죠.
만약 double invoke가 실행되었을 때 두개의 결과 값이 서로 다르다면? 해당 코드는 문제가 있다는 뜻이 됩니다.
또한 공홈에서 제공하기로는 strict 모드가 다음과 같은 문제점들을 발견해준다고 합니다. 한번 읽어보시는 것을 추천드립니다.
안전하지 않은 생명주기를 사용하는 컴포넌트 발견
레거시 문자열 ref 사용에 대한 경고
권장되지 않는 findDOMNode 사용에 대한 경고
예상치 못한 부작용 검사
레거시 context API 검사
출처 react 공홈-Strict mode
주로 double-invoked가 발생하는 함수
클래스 컴포넌트의 constructor, render 그리고 shouldComponentUpdate
클래스 컴포넌트의 getDrivedStateFromProps static 메서드
함수 컴포넌트 바디
State updater 함수(setState 의 첫 번째 인자)
useState, useMemo, useReducer 에 전달되는 함수
흠...
그런데 제가 분명히 지난번에 useState를 사용할 때 double-invoked가 발생하는 것을 발견했었는데, 오늘 포스팅을 위해 새로 프로젝트를 만들고 해당 코드를 동작하였을 때에는 또 double-invoked가 발생하지 않는군요.. 이 점은 제가 조금 더 분석해보도록 하겠습니다...😂😂
마무리
여러분들이 strict 모드를 on 해놓은 채 프로젝트를 진행하다보면, 언젠가 double-invoked 관련한 문제를 마주할 수 있습니다. 그렇다면 혹시 react strict 모드가 설정되어있는지에 대해 한번 확인해보시는건 어떨까요
이번에 라우터를 사용해서 url을 넘기면서 url은 넘어가는데 페이지는 새로고침을 하지않는 이상 바뀌지 않는 오류를 만났다. 구글에서 restrict모드를 미사용으로 바꾸면 된다고 해서 진짜 되는걸 확인을 하였다. 근데 이 모드를 사용하지 않을때 불이익이 뭔가 싶어서 알아보는데 정확하게 잡히지 않아서, 더 공부를 하면서 확인을 해봐야겠다. 일단은 임시방편으로 꺼놓은 상태로 강의를 들어봐야겠다..