궁금한 내용을 검색해보세요!
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
서근 개발노트
티스토리에 팔로잉
FRONT-END/ReactJS Clone project

[노마드/ReactJS 영화 웹 만들기] - Ch03 | 0. State?

서근
QUOTE THE DAY

“ 끝을 맺기를 처음과 같이 하면 실패가 없다. ”

- Laozi (노자)
Written by SeogunSEOGUN

[노마드/ReactJS 영화 웹 만들기] - Ch03 | 0. State?

ReactJS State

바닐라 JS에서 버튼을 클릭하면 Count가 올라가는 함수를 이벤트 리스너와 함께 구현하면 다음과 같다.

html
UNFOLDED
<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?

ReactJS로 변환

위 바닐라 JS코드를 ReactJS로 변환해 보자면

html
UNFOLDED
<!--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 해줘야 한다.

javascript
UNFOLDED
function countUp() {
counter = counter + 1;
console.log(counter);
ReactDOM.render(<Container />, root);
}

랜더링 순서

  • 애플리케이션 실행 ➜
  • ReactDOM 랜더
  • counter = 0
  • 버튼 클릭 ➜
  • 함수 실행 (countUp())
  • ReactDOM re-render

랜더링 함수 생성

그렇다면 ReactDOM.render(<Container />, root); 는 사주 사용할 거 같기 때문에 함수로 만들어 주면 더 깔끔하고 재사용이 쉬워진다.

javascript
UNFOLDED
function countUp() {
counter = counter + 1;
console.log(counter);
render();
}
function render() {
ReactDOM.render(<Container />, root);
}
//ReactDOM.render(<Container />, root); ➜
render()
전체코드
html
UNFOLDED
<!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>

TIP
 
 

하지만! 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(); 로 명명해 주면 된다.

전체코드
javascript
UNFOLDED
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


잘못된 내용이 있으면 언제든 피드백 부탁드립니다.


서근


위처럼 이미지 와 함께 댓글을 작성할 수 있습니다.