728x90

문제 상황

// _app.tsx

function App({ Component, pageProps }) {
  useEffect(() => {
    console.log('rendering')
  }, [])
  
  return <Component {...pageProps} />
}

영향을 줄만한 코드 일체없이

_app.tsx에서 위와 같이 코드를 설정했음에도

useEffect가 두번도는 큰 문제가 발생했다.

 

이것을 나중에 api요청과 처리 과정에서 발견했는데,

redux 코드에 문제가 있는건지

re-rendering 과정에 사이드 이펙트가 발생하는건지

한참을 돌고 돌아 문제의 원인을 찾았다.

(15분은 낭비한듯..)

 

문제 원인

바로, react의 strict모드 설정 이슈였다.

strict모드의 어떤 부분에서 이슈가 발생했는지

stict모드가 무엇인지 살펴보자.

 

react docs에 보면 아래와 같은 문장이 있다.

Strict mode can’t automatically detect side effects for you, 
but it can help you spot them by making them a little more deterministic. 
This is done by intentionally double-invoking the following functions:

1. Class component constructor, render, and shouldComponentUpdate methods
2. Class component static getDerivedStateFromProps method
3. Function component bodies
4. State updater functions (the first argument to setState)
5. Functions passed to useState, useMemo, or useReducer

사이드 이펙트를 방지하는데 도움을 주기위해

5가지 경우에 대해 함수를 두번 호출한다고 명시되어있다.

 

그 중에서도 내 눈에 띈것은 Function component body...

함수형 컴포넌트의 Body구문에서 두번 호출된다면

어지간하면 두번 호출된다는 것이라 생각된다.

 

문제 해결

그렇다. strict 모드를 해제하면 일단

두번 호출되는 문제는 해결된다.

// next.js 기준
// next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
    reactStrictMode: false, // <-- 이 부분 false로 변경
    swcMinify: true
};

module.exports = nextConfig;

 

Strict 모드란?

strict모드가 어떤 도움을 주는지

해제했을때 어떤 문제가 발생할 수 있는지

가볍게 살펴보자

 

문서 첫 줄에 이렇게 명시되어있다.

"StrictMode는 애플리케이션 내 잠재적인 문제를 알아내기 위한 도구이다."

그리고 "Strict 모드는 개발 모드에서만 활성화되며, 프로덕션에 영향을 주지는 않는다."

 

즉 위의 문제도 사실 프로덕션에서는 발생하지 않을 이슈였던것이다.

그럼에도 개발단에 거슬리긴 했다.

 

다른 도움되는 부분이 없다면 해제하고 마무리하는것으로 하자.

Strict가 도움을 주는 부분 6가지 (확장 예정)

1. Identifying components with unsafe lifecycles
2. Warning about legacy string ref API usage
3. Warning about deprecated findDOMNode usage
4. Detecting unexpected side effects
5. Detecting legacy context API
6. Ensuring reusable state

 

사이드 이펙트 방지가 마음에 드는데

방지를 위해 두번 요청하는 (우리가 부작용이라 생각했던) 동작이

아래와 같은 경우에 발생한다고 한다.

렌더링 단계 생명주기 메서드는 클래스 컴포넌트의 메서드를 포함

1. constructor
2. componentWillMount (or UNSAFE_componentWillMount)
3. componentWillReceiveProps (or UNSAFE_componentWillReceiveProps)
4. componentWillReceiveProps (or UNSAFE_componentWillReceiveProps)
5. getDerivedStateFromProps
6. shouldComponentUpdate
7. render
8. setState

 

 

결론

아직 대부분 class component의 생명주기 메서드들에 해당하는 내용으로 보인다.

그러므로 나는 일단 strict mode는 해제하도록 하겠다.

 

 

참고

728x90
반응형