React
를 사용하지 않고 기존의 방법으로 해당 웹 페이지를 개발 해보도록 하겠습니다.
Index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Example</title> <style> * { margin: 0; padding: 0; border: 0; } #root p { color: white; background-color: green; text-align: center; width: 200px; } #btn_plus { background-color: red; border: 2px solid #000000; font-size: 15px; width: 200px; } </style> <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <script type="text/javascript"> const root = document.querySelector("#root"); const btn_plus = document.querySelector("#btn_plus"); let i=0; // root id를 가진 div 태그에 p태그로 해당 문자열을 초기값으로 설정 해줍니다. root.innerHTML = "<p>init: 0</p>"; // button 클릭 이벤트가 발생하면 1씩 증가 시켜주는 함수 입니다. btn_plus.addEventListener("click", () => { root.innerHTML = `<p>init: ${i++}</p>`; }); </script> </head> <body> <div id="root"></div> <button id="btn_plus">+</button> </body> </html>
- 이처럼 기존의 프론트엔드 개발 방식은 먼저
HTML
로 기본구조를 잡고CSS
로 스타일을 입힌뒤JS
로DOM
을 제어 합니다.script
의type
디폴트가text/javascript
로 지정이 되기 때문에 굳이 선언을 해줄 필요는 없으며script
와 동일한 문장이라고 봐도 무방합니다.
- React를 사용하지 않고 컴포넌트만을 이용하여 해당 웹 페이지를 개발 해보도록 하겠습니다.
Index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Example</title> <style> * { margin: 0; padding: 0; border: 0; } #root p { color: white; background-color: green; text-align: center; width: 200px; } #btn_plus { background-color: red; border: 2px solid #000000; font-size: 15px; width: 200px; } </style> <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> </head> <body> <div id="root"></div> <button id="btn_plus">+</button> <script> const component = { // 초기값 message: "init", count: 0, render() { return `<p>${this.message}: ${this.count}</p>` } }; function render(rootElement, component) { // component.render()의 return 값을 반환 rootElement.innerHTML = component.render(); } // 초기화 render(document.querySelector("#root"), component); // button 클릭 이벤트 발생시 값을 1씩 증가 document.querySelector("#btn_plus").addEventListener("click", () => { component.message = "update"; component.count = component.count + 1; // 값이 변경될 때 마다 반드시 render를 해줘야 한다. render(document.querySelector("#root"), component); }) </script> </body> </html>
- 이처럼
React
를 이용하지 않고Component
만을 사용하여 개발하면 값이 변경될 때 마다render
를 해줘야 하는 번거로움이 있습니다.
Index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Example</title> <style> * { margin: 0; padding: 0; border: 0; } #root p { color: white; background-color: green; text-align: center; width: 200px; } #btn_plus { background-color: red; border: 2px solid #000000; font-size: 15px; width: 200px; } </style> <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> </head> <body> <div id="root"></div> <button id="btn_plus">+</button> <script> console.log(React); console.log(ReactDOM); let number = 0; // component 생성 const component = props => { // <p>""</p>, p 태그 안에 들어갈 내용을 정의 return React.createElement("p", null, `${props.message} : ${props.count}`); } // 초기화 & ReactDOM.render(리엑트 컴포넌트, 리엑트 컴포넌트가 그려지는 곳); // React.createElement => React Component 방식 ReactDOM.render(React.createElement(component,{message: "init", count: number}, null), document.querySelector("#root")); document.querySelector("#btn_plus").addEventListener("click", () => { // 업데이트 & ReactDOM.render(리엑트 컴포넌트, 리엑트 컴포넌트가 그려지는 곳); // React.createElement => React Component 방식 ReactDOM.render(React.createElement(component,{message: "update", count: `${number++}`}, null), document.querySelector("#root")); }); </script> </body> </html>
- 값이 변경될 때 마다
render
를 하지 않아도 된다.
React.createElement(type, [props], [...children])
라는 API
를 통해 컴포넌트를 생성합니다.기본 문법
React.createElement( type, // 태그 요소 | 리액트 컴포넌트 | React.Fragment [props], // 리액트 컴포넌트에 넣어주는 객체 데이터 [ ... children] // 화면에 출력되는 요소 );
type
부분에는HTML
태그 타입,React
컴포넌트 타입,React Fragment
타입 중 하나가 올 수 있습니다.
type => 태그 이름 문자열
<div id="root"></div>
// <h1>type 이 "태그 이름 문자열" 입니다.</h1> ReactDOM.render( React.createElement("h1", null, `type 이 "태그 이름 문자열" 입니다.`), document.querySelector("#root") );
type => React Component
<div id="root"></div>
// 컴포넌트 생성 const Component = () => { return React.createElement("p", null, `type 이 "React 컴포넌트" 입니다.`) }; // Component 내용 => <p>type 이 "React 컴포넌트" 입니다.</p> ReactDOM.render( React.createElement(Component, null, null), document.querySelector("#root") );
type => React.Fragment
ReactDOM.render( React.createElement( React.Fragment, null, `type 이 "React Fragment" 입니다.` ) )
React.Fragment
는 위의 두 예들과 달리 별도의 다른 태그가 없이root
요소에 내용이 입력된 것을 확인할 수 있습니다.
- 개발 서버를 실행하니
console
탭에 이런Error
메시지가 출력 되었다.
Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot
- 새로 나온 리액트
18
에서는ReactDOM.render
가 아니라createRoot
를 사용해야 한다는 것 같다.
해결 방안