티스토리 뷰

반응형

nextjs를 진행하다 보면, 새로고침 시 console.log가 여러 번 찍히는 현상이 발생했다. 관련 이슈에 대한 조사를 진행하면서, 같은 고민을 할 개발자 분들에게 공유해 보고자 한다. 해결책 위주로 설명을 풀어보겠다. 아래의 여러 case 중에 어느 부분과 연관이 되어 있는지 확인해 보자.

 

 

1. next.config.js 의 reactStrictMode

react 18이 넘어오면서 엄격모드에 관련된 console.log가 아래와 같이 2번 찍히는 경우가 있다.

 

 

reactStrictMode가 true라 엄격 모드 확인에 관련된 console이 회색으로 찍히는 것이다. 이러한 현상은 development 환경에서만 발생하며, production 환경에서는 발생하지 않는다. development 환경에서도 회색 console.log를 지우려면 관련 코드를 아래와 같이 reactStrictMode를 true => false로 변경해 주면 된다. 

 

// next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: false
};

module.exports = nextConfig;

 

추가적인 설명은 아래의 필요한 부분으로 이동해서 보면 된다.

 

[nextjs] 실무 개발 환경/배포 환경 설정(.env)

[nextjs] next.config.js 기초 정리 실습

[nextjs] next.config.js 내부의 reactStrictMode 설정

 

 

2. React 18 버전 이슈

우선은 아래의 공식문서 내용을 먼저 참고하자.

 

 

기본적으로 React 18은 development mode에서 컴포넌트를 2번 렌더 한다.  함수형 컴포넌트가 나오기 이전 react에는 pure components라는 개념이 기본적으로 있었다. pure components의 기본 개념은 props 데이터의 변경이 있다면, 화면을 re-render하는 개념으로 간단히 이해를 하면 좋다. 정리하면, react 18에서는 기본적으로 pure에 대한 탐지를 위해 2번 렌더를 한다. 따라서 component가 생성되기 이전에는 변수의 변화가 발생하면 안 되는 것이 기본적인 react의 원리라고 할 수 있다. 따라서 side-effect가 발생하기 않도록 하기 위해서는 component의 re-render 시 같은 input이 들어가면 같은 output이 도출되어야 함을 인지하고 코드를 짜야한다.  이러한 pure하지 않는 문제를 판단하기 위해서 react는 2번 컴포넌트를 렌더링 하는 것이다. (react 18과 관련된 버전 문제라는 이야기가 구글링 하다 보면 있기는 하지만,  큰 이슈라기보다는 react의 특징으로 나는 이해를 했다.) 그렇다면 이러한 React의 특징을 핸들링하는 방식에 대해서도 아래에서 알아보자.

 

 

3. remounting 이후의 handling

기본적으로 React에서는 bug를 찾기 위해 development 과정에서 의도적으로 component를 remount 함을 위에서 이해했다. 그렇다면, 우리는 질문을 재정의해야 한다. 어떻게 한 번만 render 하냐가 아니라, re-render 이후에 어떻게 핸들링을 해야 할지에 대해 알아보아야 한다.

 

우리가 주의하여 개발해야 할 부분은 바로 cleanup 관련 함수라고 할 수 있다. 이 부분의 핵심은 사용자 기준으로는 한 번만 실행되지만, 개발 입장에서는 2번 실행이 되는 것을 한번만 실행이 되도록 변경해야 한다는 것이다. 2번이 실행되는 react에서 가능하면 cleanup을 활용하여 원상복귀를 시켜주어야 한다. 관련된 예는 아래와 같다.

 

// event cleanup
useEffect(() => {
  function handleScroll(e) {
    console.log(e.clientX, e.clientY);
  }
  window.addEventListener('scroll', handleScroll);
  return () => window.removeEventListener('scroll', handleScroll);
}, []);


// animations
useEffect(() => {
  const node = ref.current;
  node.style.opacity = 1; // Trigger the animation
  return () => {
    node.style.opacity = 0; // Reset to the initial value
  };
}, []);


// fetching data
useEffect(() => {
  let ignore = false;
  async function startFetching() {
    const json = await fetchTodos(userId);
    if (!ignore) {
      setTodos(json);
    }
  }
  startFetching();
  return () => {
    ignore = true;
  };
}, [userId]);

 

조금 더 쉽게 말하면, 변화된 데이터를 원상 복귀시켜줘야 한다. 그래야 재접속 시 관련 에러가 발생하지 않는다.

 

 

 

4. package.json 변경

nextjs에서는 기본적으로 NODE_ENV를 2가지를 제공한다. development와 production 모드이다. 우선은 development에서는 기본적으로 debug 모드가 포함되어 있기 때문에 우리가 의도한 SSR이 잘 안 나타날 수도 있다. 이러한 문제점을 해결하기 위해서 아래와 같이 npm run dev 부분의 script 부분을 변경하면, production 모드로 실행이 잘 될 것이다.

 

{
  "private": true,
  "scripts": {
    "dev": "NODE_ENV=production next",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "latest",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}

 

환경 변수 세팅은 개발 환경에 따라 달라질 수 있다. 관련 조금 더 디테일한 설명은 아래를 참고하자.

 

[nextjs] 실무 개발 환경/배포 환경 설정(.env)

 

 

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함