React v17.0 요약

이 글은 React 공식 문서의 Blog Post - React v17.0 를 요약한 글입니다.

React 17 은 2020.10.20 Release 되었습니다.

No New Features

React 17 에는 개발자를 위한 새로운 기능은 없다. 대신 이번 배포의 최우선 목표는 React 자체를 더 쉽게 업그레이드 하는 것이다.

특히 React 17 은 한 버전의 React 로 관리되는 tree (component tree 를 의미하는 것 같다.) 를 다른 버전의 React 로 관리되는 tree 안으로 embed 하는 것을 더 안전하게 해주는 “디딤돌” release 이다.

또한 다른 기술로 작성된 app 들에 React 를 embed 하는 것을 쉽게 해준다.

Gradual Upgrades

점진적 업그레이드

만약 React 16 에서 17 로 업그레이드 한다면, 보통 한 번에 app 전체를 업그레이드 할 것이다. 대부분 이런 업그레이드가 잘 이루어지지만, codebase 가 수년 전에 작성되었고 활발히 관리되지 않았다면 급격히 어려워진다.

그리고 page 상에 두 버전의 React 를 사용하는 것은 가능해왔지만 이는 취약하고 event 관련 문제를 발생시켜왔다.

React 17 에서는 이런 문제들을 해결하고 있다.
즉, React 18 과 future 버전에서는 더 많은 옵션 (기능) 을 갖게 될 것이다.
첫 번째는 버전 업그레이드를 부분 부분 따로 할 수 있는 옵션이다. 예를 들어, app 을 전반적으로 React 18 로 migrate 하되 lazy-load 되는 dialog 또는 subroute 를 React 17 로 유지할 수 있게 된다.

여전히 한 번에 업그레이드 하는 것이 대부분의 앱에 best solution 이겠지만, 규모가 크고 관리가 잘 되어오지 않은 앱에게는 충분히 고려해 볼만한 옵션이다. React 17 은 이런 앱들을 뒤쳐지지 않도록 한다.

Changes to Event Delegation

Event 위임의 변경 사항

점진적 업그레이드를 가능하게 하도록 하기 위해서 React event system 에 변화가 불가피했다. React 17 이 major release 인 이유는 이 변화들이 잠재적으로 중요하기 때문이다.

React 17 에서, React 는 더 이상 Event Handler 를 내부 document level 에 연결하지 않는다. 대신에, React tree 가 render 되는 root DOM container 에 연결한다.

const rootNode = document.getElementById("root");
ReactDOM.render(<App />, rootNode);

React 16 과 그 이 전 버전은 document.addEventListener() 를 사용했지만, React 17 과 그 이 후 버전은 rootNode.addEventListenter() 를 내부적으로 사용할 것이다.

수 년 동안 React 와 non-React code 통합 에 관련된 많은 문제들이 report 되어 왔는데 그 문제들이 이 변경사항으로 인해 해결 되었음을 confirm 한다.

Other Breaking Changes

다른 주요 변경 사항

참고 The React 17 RC - blog post
(생각보다 내용이 많아 시간이 날 때 다시 정리 해야겠다…)

이번 release 에선 변화를 최소한으로 가져갔다고 한다. 이전 release 에서 deprecated 된 method 들도 우선 그대로 유지하는 등등…
(Facebook 팀에서는 React 17 적용을 위해 수정한 컴포넌트가 전체 약 10만개 중 20개도 안된다고 한다.)

New JSX Transform

새로운 JSX 변환 방식

참조 New JSX Transform - blog post

간략히만 내용을 요약하자면

JSX 를 React.createElement(...) 로 변환하던 Babel 이 이제 아래 처럼 자동으로 필요한 함수를 import 해서 사용한다.

// Inserted by a compiler (don't import it yourself!)
//  -> compiler 에 의해 추가됨 (직접 import 하지 마시오!)
import { jsx as _jsx } from "react/jsx-runtime";

function App() {
  return _jsx("h1", { children: "Hello world" });
}

이제 React Component 를 작성하기 위해 import React from 'react' 문을 쓰지 않아도 된다.

Test 완료

none import test

Test 환경

  • “react”: “^17.0.1”
  • “react-dom”: “^17.0.1”
  • “@babel/core”: “^7.12.3”
  • “@babel/preset-react”: “^7.12.5”
  • .babelrc
    {
      "presets": [
        ["@babel/preset-react", {
          "runtime": "automatic"
        }]
      ]
    }
    

bundle size 도 조금 작아진다고 한다.

단, 이 새로운 transform 방식은 선택적이다. 예전 방식도 여전히 잘 동작하며 지원을 멈출 계획은 없다고 한다.

React 16.14.0 / 15.7.0 / 0.14.10 버전에도 minor release 로 이 JSX transform 방식을 사용할 수 있도록 업데이트 했다고 한다.

Hook 을 사용하기 위해서는 import { useState } from 'react' 를 해줘야 한다.

Install

  • npm
npm install react@17.0.0 react-dom@17.0.0
  • yarn
yarn add react@17.0.0 react-dom@17.0.0

Reference

React 공식 문서의 Blog Post - React v17.0