React 19로 올렸더니 propTypes와 findDOMNode가 사라져서 깨진 부분
문제 발생
React 18에서 19로 올린 뒤 두 가지가 동시에 일어났습니다. 하나는 앱이 시작조차 못 하는 오류였고, 다른 하나는 아무 경고 없이 기본값이 사라져 화면에 undefined가 찍히는 문제였습니다.
// 1) 즉시 터진다
ReactDOM.render(<App />, document.getElementById("root"));
// TypeError: ReactDOM.render is not a function
// 2) 조용히 달라진다
function Heading({ text }) { return <h1>{text}</h1>; }
Heading.defaultProps = { text: "Hello, world!" }; // 더 이상 적용되지 않음원인 분석
React 19는 여러 버전에 걸쳐 deprecated였던 API를 실제로 제거했습니다. 업그레이드가 까다로운 이유는 제거 방식이 두 종류이기 때문입니다.
즉시 터지는 것 — 함수 자체가 없어져 첫 실행에서 바로 드러납니다.
| 제거된 것 | 대체 |
|---|---|
ReactDOM.render | createRoot(container).render(<App />) |
ReactDOM.hydrate | hydrateRoot(container, <App />) |
ReactDOM.unmountComponentAtNode | root.unmount() |
ReactDOM.findDOMNode | useRef로 DOM 참조 |
react-dom/test-utils의 act | import { act } from "react" |
조용히 달라지는 것 — 호출은 성공하는데 효과만 없어집니다. 테스트가 없으면 배포 후에 발견됩니다.
- 함수 컴포넌트의
propTypes와defaultProps— 검증도 기본값 주입도 일어나지 않습니다. - 문자열 ref(
ref="input") — 콜백 ref로 바꿔야 합니다. - 레거시 컨텍스트(
contextTypes,getChildContext) —createContext로 옮겨야 합니다.
findDOMNode는 특히 조심할 부분입니다. 직접 쓰지 않아도 오래된 서드파티 컴포넌트가 내부에서 쓰고 있는 경우가 많아, 우리 코드를 다 고쳐도 라이브러리에서 터집니다.
해결 방안
- 기본값은 매개변수 기본값으로 옮깁니다. 타입 검증은 TypeScript가 대신합니다.
// 이전
function Heading({ text }) { return <h1>{text}</h1>; }
Heading.defaultProps = { text: "Hello, world!" };
// 이후
function Heading({ text = "Hello, world!" }) { return <h1>{text}</h1>; }findDOMNode는 ref로 대체합니다. 감싸는 DOM 노드를 추측하는 대신 원하는 노드를 직접 가리킵니다.
function AutoselectingInput() {
const ref = useRef(null);
useEffect(() => { ref.current.select(); }, []);
return <input ref={ref} defaultValue="Hello" />;
}- 먼저 18의 마지막 마이너로 올려 경고를 모두 없앱니다. 19에서 제거된 것들은 18에서 이미 경고를 내고 있었으므로, 경고가 0이 된 상태에서 19로 올리면 남는 문제가 훨씬 적습니다.
- 의존성이 19를 지원하는지 확인합니다.
findDOMNode나 문자열 ref는 우리 코드보다 오래된 라이브러리에 남아 있을 확률이 높습니다. - 공식 codemod를 활용합니다. 업그레이드 가이드가 제공하는 codemod로 기계적인 치환은 자동화할 수 있습니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.