![[노마드/ReactJS 영화 웹 만들기] - Ch03 | 0. State? [노마드/ReactJS 영화 웹 만들기] - Ch03 | 0. State?](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
ReactJS State
바닐라 JS에서 버튼을 클릭하면 Count가 올라가는 함수를 이벤트 리스너와 함께 구현하면 다음과 같다.
<body> <span>클릭된 숫자: 0</span> <button id="btn">클릭</button> </body> <script> let count = 0; let span = document.querySelector('span'); const btn = document.getElementById('btn'); function handleClick() { console.log('클릭'); count = count + 1; span.innerText = `클릭된 숫자: ${count}`; } btn.addEventListener('click', handleClick); </script>
바닐라 JS와 ReactJS는 값이 변경될 때 UI가 어떻게 rerender
되는지 확연하게 구분된다.
ReactJS는 UI에서 바뀐 부분만 업데이트해주고,
바닐라 JS는 변경된 태그 전체를 업데이트한다.
![[노마드/ReactJS 영화 웹 만들기] - Ch03 | 0. State? [노마드/ReactJS 영화 웹 만들기] - Ch03 | 0. State?](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
![[노마드/ReactJS 영화 웹 만들기] - Ch03 | 0. State? [노마드/ReactJS 영화 웹 만들기] - Ch03 | 0. State?](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
ReactJS로 변환
위 바닐라 JS코드를 ReactJS로 변환해 보자면
<!--ReactJS 구현부--> <script type="text/babel"> const root = document.getElementById('root'); let counter = 0; function countUp() { counter = counter + 1; console.log(counter); } const Container = () => ( <div> <h3 id="main-title">클릭 횟수: {counter}</h3> <button id="new-btn" onClick={countUp}> 카운트 올리기 </button> </div> ); ReactDOM.render(<Container />, root); </script>
오류 확인
하지만 버튼을 클릭하면, 클릭 이벤트는 정상적으로 작동하지만 UI에 반영되지는 않는다.
웹 페이지가 처음 실행되면 Container
은 함수이기 때문에 바로 실행되지는 않고, 페이지가 로드되면서 Container
컴포넌트가 딱 한 번 랜더링 된다.
이벤트 리스너를 등록하고 클릭하면 conutUP
함수가 실행되지만, 최초로 Container
를 랜더링 하고 더 이상 rerender
해주지 않았기 때문에 UI가 업데이트되지 않는 것이다.
해결 방법
이를 해결하기 위해서는 conutUP
함수가 실행될 때마다 Container
컴포넌트를 rerender
해줘야 한다.
function countUp() { counter = counter + 1; console.log(counter); ReactDOM.render(<Container />, root); }
랜더링 순서
- 애플리케이션 실행 ➜
ReactDOM 랜더
➜counter = 0
➜- 버튼 클릭 ➜
- 함수 실행
(countUp())
➜ ReactDOM re-render
랜더링 함수 생성
그렇다면 ReactDOM.render(<Container />, root);
는 사주 사용할 거 같기 때문에 함수로 만들어 주면 더 깔끔하고 재사용이 쉬워진다.
function countUp() { counter = counter + 1; console.log(counter); render(); } function render() { ReactDOM.render(<Container />, root); } //ReactDOM.render(<Container />, root); ➜ render()
<!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>Document</title> </head> <body> <div id="root"></div> </body> <script crossorigin src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <!--Babel 스크립트--> <script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <!--ReactJS 구현부--> <script type="text/babel"> const root = document.getElementById('root'); let counter = 0; function countUp() { counter = counter + 1; console.log(counter); render(); } function render() { ReactDOM.render(<Container />, root); } const Container = () => ( <div> <h3 id="main-title">클릭 횟수: {counter}</h3> <button id="new-btn" onClick={countUp}> 카운트 올리기 </button> </div> ); render(); </script> </html>
하지만! render
함수를 만들어 사용하는 방법이 최고의 방법은 아니다! 더 쉬운 방법이 있는데 왜냐하면 값이 바뀔 때마다 render()
함수를 넣어줄 순 없는 노릇이기 때문이다. 다음 포스트에서 이것을 어떻게 개선해 나아갈지 알아보자
React18 버전
React 18 버전부터는 createRoot
를 사용해야 한다. 우선 Container
를 전역에서 한번, 버튼 클릭할 때마다 rendering
을 해야 하는데ReactDOMClient.createRoot(root).render()
를 두 곳에 모두 쓸 경우와 function render()
를 호출한 경우 모두 작동은 되지만 console
창에 ReactDOMClient.createRoot()
대신 root.render()
를 호출하라고 뜨게 된다.
React18부터는 ReactDOMClient.createRoot()
를 변수에 담아 사용해야 한다.
const root = ReactDOM.createRoot(document.getElementById("root"));
라고 root
변수를 만들어 주고, render
함수를 만들지 않은 상태로 렌더링이 필요한 부분에 root.render();
로 명명해 주면 된다.
const root = ReactDOM.createRoot(document.getElementById('root')); let counter = 0; function countUp() { counter++; Render(); } function Render() { return root.render(<Container />); } const Container = () => ( <div> <h3 id="main-title">클릭 횟수: {counter}</h3> <button id="new-btn" onClick={countUp}> 카운트 올리기 </button> </div> ); Render();
GitHub - Seogun95/Movie-web-servic-ReactJS: ReactJS로 영화 웹 서비스 만들기 노마드 코더 클론 코딩
ReactJS로 영화 웹 서비스 만들기 노마드 코더 클론 코딩. Contribute to Seogun95/Movie-web-servic-ReactJS development by creating an account on GitHub....
github.com
'FRONT-END > ReactJS Clone project' 카테고리의 다른 글
[노마드/ReactJS 영화 웹 만들기] - Ch03 | 4. State Functions (0) | 2023.01.28 |
---|---|
[노마드/ReactJS 영화 웹 만들기] - Ch03 | 1~2. setState (0) | 2023.01.26 |
[노마드/ReactJS 영화 웹 만들기] - Ch02 | 6. 컴포넌트 사용 (0) | 2023.01.15 |
[노마드/ReactJS 영화 웹 만들기] - Ch02 | 5. JSX 사용법 (0) | 2023.01.15 |
[노마드/ReactJS 영화 웹 만들기] - Ch02 | 3. Events in React (1) | 2023.01.15 |