React.JS) JS VS React.JS - 2. React로 상태관리하기

송민경's avatar
Sep 20, 2024
React.JS) JS VS React.JS - 2. React로 상태관리하기

1. JS로 기본 클릭 이벤트 만들기

  • 상태가 변하는 버튼 클릭 이벤트 만들기
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <span>총 클릭 수: 0</span> <button id="btn">Click me</button> </body> <script> let counter = 0; const button = document.getElementById("btn"); const span = document.querySelector("span"); function handleClick() { counter = counter + 1; span.innerText = `총 클릭 수: ${counter}`; } button.addEventListener("click", handleClick); </script> </html>
notion image
notion image
notion image
 

Resct.JS로 만들어보기

2. React와 ReactDOM 라이브러리를 웹 페이지에 추가하기

<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
 

3. Container 컴포넌트를 이용하여 h3와 button 요소 만들기

React를 사용하여 간단한 Container 컴포넌트를 만들어 렌더링
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); // Container 컴포넌트 정의 function Container() { return ( <div> <h3>총 클릭 수: 0</h3> <button>Click me</button> </div> ); } ReactDOM.render(<Container />, root); </script> </html>
notion image
 

4. 변수 연결하기

  • 변수를 사용하여 상태를 표현
  • 0으로 해놓고 함수에서 요소를 가져와서 변경할 필요없이 바껴야될 부분에 바로 {변수} 이용하기
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); let counter = 10; // Container 컴포넌트 정의 function Container() { return ( <div> <h3>총 클릭 수:{counter}</h3> <button>Click me</button> </div> ); } ReactDOM.render(<Container />, root); </script> </html>
notion image
 

5. 이벤트 연결하기

  • 버튼 클릭 시 이벤트를 처리
  • 요소 뒤에 이벤트={이벤트명} 이용하기
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); let counter = 0; function countUp() { counter = counter + 1; } // Container 컴포넌트 정의 function Container() { return ( <div> <h3>총 클릭 수:{counter}</h3> <button onClick={countUp}>Click me</button> </div> ); } ReactDOM.render(<Container />, root); </script> </html>
  • eventListener가 작동해서 counter는 바뀌고 있으나 UI에 업데이트가 안되고 있음
notion image
  • Container를 렌더링해서 root에 담는 그 순간 counter가 0인 상태로 로드가 됨
  • 클릭하면 counter를 업데이트시키고만 있음
 

6. UI 업데이트하기

  • 클릭 시 UI를 다시 렌더링하여 상태 변경을 반영해야 함
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); let counter = 0; function countUp() { counter = counter + 1; ReactDOM.render(<Container />, root); } // Container 컴포넌트 정의 function Container() { return ( <div> <h3>총 클릭 수:{counter}</h3> <button onClick={countUp}>Click me</button> </div> ); } ReactDOM.render(<Container />, root); </script> </html>
notion image
notion image
  • 로드하는 부분을 함수로 만들어 재사용하기
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); let counter = 0; function countUp() { counter = counter + 1; render(); } function render() { ReactDOM.render(<Container />, root); } // Container 컴포넌트 정의 function Container() { return ( <div> <h3>총 클릭 수:{counter}</h3> <button onClick={countUp}>Click me</button> </div> ); } render(); </script> </html>
 

7. React의 효율적인 렌더링

  • React.JS는 이전에 렌더링된 컴포넌트를 확인하고 다음에 렌더링될 컴포넌트를 확인해서 다른 부분만 파악해서 그 부분만 렌더링 됨
  • JS의 경우
    • 변경되는 값이 있는 요소가 업데이트 됨
      • 매번 DOM을 업데이트
      • notion image
  • React의 경우
    • 변수만 업데이트 됨
      • "Virtual DOM"을 사용
      notion image
 

8. React.JS 어플 내에서 데이터를 보관하고 자동으로 렌더링하기

  • React의 useState 훅을 사용하여 상태를 관리하고 클릭 시 상태가 자동으로 업데이트하기
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); function App() { const data = React.useState(); console.log(data); return ( <div> <h3>총 클릭 수: 0</h3> <button>Click me</button> </div> ); } ReactDOM.render(<App />, root); </script> </html>
notion image
  • data값을 주어 0으로 초기화하고 그 값을 바꾸는 함수 사용하기
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); function App() { const data = React.useState(0); console.log(data); return ( <div> <h3>총 클릭 수: 0</h3> <button>Click me</button> </div> ); } ReactDOM.render(<App />, root); </script> </html>
notion image
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); function App() { const data = React.useState(10); console.log(data); return ( <div> <h3>총 클릭 수: {data[0]}</h3> <button>Click me</button> </div> ); } ReactDOM.render(<App />, root); </script> </html>
notion image
 

9. 배열에서 값을 추출하는 방법

  • 배열에서 요소를 꺼내 이름을 지정하는 방식
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); function App() { const data = React.useState(0); const counter = data[0]; const modifier = data[1]; return ( <div> <h3>총 클릭 수: {data[0]}</h3> <button>Click me</button> </div> ); } ReactDOM.render(<App />, root); </script> </html>
notion image
  • 배열 디스트럭처링 문법을 사용
    • 반환하는 배열의 첫 번째 요소를 counter, 두 번째 요소를 modifier로 바로 할당하는 방법
    • <!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); function App() { const [counter, modifier] = React.useState(0); return ( <div> <h3>총 클릭 수: {counter}</h3> <button>Click me</button> </div> ); } ReactDOM.render(<App />, root); </script> </html>
notion image
  • 상태 업데이트하기
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); function App() { let [counter, modifier] = React.useState(0); const onClick = () => { counter = counter + 1; console.log(counter); }; return ( <div> <h3>총 클릭 수: {counter}</h3> <button onClick={onClick}>Click me</button> </div> ); } ReactDOM.render(<App />, root); </script> </html>
notion image
 
  • 리렌더링하기
  • 새로운 값을 가지고 렌더링하기
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); function App() { const [counter, modifier] = React.useState(0); const onClick = () => { modifier(120); }; return ( <div> <h3>총 클릭 수: {counter}</h3> <button onClick={onClick}>Click me</button> </div> ); } ReactDOM.render(<App />, root); </script> </html>
notion image
  • counter와 같은 데이터를 숫자형 데이터로 전달하고 그 데이터를 바꿀 함수를 줘서 바꾸고 공시에 렌더링되어 UI가 자동 업데이트 됨
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); function App() { const [counter, setCounter] = React.useState(0); const onClick = () => { setCounter(counter + 1); }; return ( <div> <h3>총 클릭 수: {counter}</h3> <button onClick={onClick}>Click me</button> </div> ); } ReactDOM.render(<App />, root); </script> </html>
notion image
notion image
 

9. state 변경 방법

  • 현재 상태
    • 다른 곳에서도 counter가 업데이트 될 수 있으니 좋은 상태는 아님
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); function App() { const [counter, setCounter] = React.useState(0); const onClick = () => { setCounter(counter + 1); }; return ( <div> <h3>총 클릭 수: {counter}</h3> <button onClick={onClick}>Click me</button> </div> ); } ReactDOM.render(<App />, root); </script> </html>
  • setCounter를 통해서 직접 원하는 값 넣기
    • 클릭할때 값이 변화되진 않음
  • 이전 값을 이용해서 현재 값 계산하기
setCounter(counter + 1);
  • state 기반으로 계산하기 위해 함수 이용하기(현재값, 상태)
    • current 값이 현재 값이라고 확실히 보장됨
<!DOCTYPE html> <html lang="en"> <body> <div id="root"></div> </body> <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script> <script type="text/babel"> // ReactDOM을 사용하여 React 요소를 렌더링하기 const root = document.getElementById("root"); function App() { const [counter, setCounter] = React.useState(0); const onClick = () => { setCounter((current) => current + 1); }; return ( <div> <h3>총 클릭 수: {counter}</h3> <button onClick={onClick}>Click me</button> </div> ); } ReactDOM.render(<App />, root); </script> </html>
notion image
notion image
Share article

vosw1