본문 바로가기

JS/React

2. React Quick Start - React.dev 정리2

5-1. 이벤트에 반응하기 

컴포넌트 안에 EventHandler 함수를 선언하여 이벤트에 대하여 응답할 수 있다. 

export default function MyButton(){
  
  function handleClick() {
    alert('클릭되었음..!');
  }

  return (
    <button onClick={handleClick}>
      클릭하세요
    </button>
  );
}

 <button onClick={handleClick}> 이 부분을 본다면, HTML에서 onClick 이벤트를 줄 때와 같이 onClick={handleClick()괄호를 사용하지 않고 EventHandler 함수 자체를 전달하였다. 만약, onClick={handleClick()} 과 같이 괄호()를 사용하게 된다면, 버튼을 클릭을 했을 때가 아니라, 화면이 로드되었을 때 바로 alert창이 즉시실행되어 버린다.  

 

 

5-2. 화면을 업데이트하기

버튼을 클릭한 횟수를 세고 싶은 것처럼 컴포넌트에 정보를 저장하고 화면에 출력하고 싶은 경우가 자주 있다. 이를 위해 컴포넌트에 상태(state)를 추가하여 구현할 수 있다.  

 

우선, React에서 useState를 불러온다. 

import { useState } from 'react';

 

이제  컴포넌트 내에서 상태 변수를 선언할 수 있다. 

export default function MyButton() {

  const [count, setCount] = useState(0);

  // ...
  
}

 

이제 useState에서 현재 상태인 count와 이것을 업데이트 하는 setCount함수를 얻었다. (이 경우, 어떤 이름을 부여해도 상관은 없으나 보통 [something, setSomething]과 같이 작성하는 것이 관례이다. 

 

버튼이 처음 표시될 때, useState에 0을 전달하였기 때문에 count는 0이 된다. 상태를 변경하려면 setCount()를 호출하여 새 값을 전달하면 된다.(버튼을 누르면 count가 증가) 

export default function MyButton() {

  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return(
    <button onClick={handleClick}>
    클릭이 {count}번 되었음
    </button>
  );
  
}

React는 컴포넌트 함수를 다시 호출한다. 이 경우, count는 1이 되고 그 다음엔 2가 되며 계속 이렇게 증가할 것이다. 

 

만약, 같은 컴포넌트를 여러번 렌더링한다면, 각각의 컴포넌트는 고유의 상태를 가지게 된다. 각 버튼을 따로 클릭해보자. 

import { useState } from 'react';

export default function MyApp() {

  return (
    <div>
      <h1>별도로 업데이트 되는 count</h1>
      <MyButton /> <br /><br />
      <MyButton />
    </div>
  );
}

function MyButton() {

  const [count, setCount] = useState(0);


  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      클릭이 {count}번 되었음
    </button>
  );

}

각 버튼이 자신의 count 상태만을 '기억'하고 다른 버튼에는 영향을 미치지 않는 것을 볼 수 있다. 

 

 

Hooks 사용하기 

use로 시작하는 함수들은 Hooks이라고 불린다. useState는 React에서 제공하는 내장 Hook이며, 다른 내장 Hook은 API참조에서 찾아 볼 수 있고 또한 기존의 Hook을 조합하여 직접 Hook을 작성할 수도 있다. 

Hooks는 다른 함수들에 비해 제한적이다. 컴포넌트의 맨 위(혹은 다른 Hook 내부)에서만 Hook을 호출할 수 있다. 만약 조건문이나 반복문 안에서 useState를 사용하고 싶다면, 새로운 컴포넌트를 추출하여 그 안에 넣어주면 된다. 

 

 

6. 컴포넌트 간 데이터를 공유하는 방법 

위 예제들은, 각 MyButton은 독립적으로 count를 가지고 있었으며, 각 버튼이 클릭되었을 때 클릭된 버튼의 count만 변경이 되었다. 

 

그러나, 종종 컴포넌트 간 데이터를 공유하거나 함께 업데이트가 되어야 하는 경우가 있기도 하다. 

 

두 개의 MyButton 컴포넌트가 동일한 count를 표시하고 함께 업데이트되도록 하려면, 개별 버튼에서 상태를 '위로' 이동하여 모든 버튼을 포함하는 가장 가까운 컴포넌트인 MyApp으로 이동해야 한다. 

 

이제 버튼 중 하나를 클릭하면, MyApp의 count가 변경되어 두 개의 MyButton count가 변경될 것이다 

 

코드로 표현하는 방법은 다음과 같은데, 먼저 MyButton에서 MyApp으로 상태를 옮긴다. 

import { useState } from 'react';

export default function MyApp() {

  // 이동한 코드-------------------------
  const [count, setCount] = useState(0);


  function handleClick() {
    setCount(count + 1);
  }
  // ----------------------------------

  return (
    <div>
      <h1>별도로 업데이트 되는 count</h1>
      <MyButton /> <br /><br />
      <MyButton />
    </div>
  );
}

function MyButton() {

  // 위로 이동

  return (
    <button onClick={handleClick}>
      클릭이 {count}번 되었음
    </button>
  );

 

그 다음, MyApp에서 공유된 click handle와 함께 상태를 각 MyButton으로 전달한다. 이전에 <img>와 같은 내장 태그에서 했던 것처럼 JSX 중괄호를 사용하여 MyButton으로 정보를 전달할 수 있다.

import { useState } from 'react';

export default function MyApp() {

  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>별도로 업데이트 되는 count</h1>
      
      //----------------------------------------------
      <MyButton count={count} onClick={handleClick} /> 
      <br /><br />
      <MyButton count={count} onClick={handleClick} />
       //----------------------------------------------
       
    </div>
  );
}

 

이렇게 전달하는 정보를 props라고 한다. 이제 MyApp 컴포넌트에는 count 상태와 handleClick 이벤트핸들러가 포함되어 있으며, 두 props를 각 버튼의 props로 전달한다. 

 

마지막으로, MyButton에서 그 부모 컴포넌트에 전달한 props를 읽도록 변경하자. 

import { useState } from 'react';

export default function MyApp() {

  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>함께 업데이트 되는 count</h1>
      <MyButton count={count} onClick={handleClick} /> 
      <br /><br />
      <MyButton count={count} onClick={handleClick} /> 
    </div>
  );
}

//-----------------------------------
function MyButton({count, onClick}) {

  return (
    <button onClick={onClick}>
//-----------------------------------
      클릭이 {count}번 되었음
    </button>
  );
  
}

 

버튼을 클릭하면 onClick 핸들러가 실행된다. 각 버튼의 onClick props는 MyApp 내부의 handleClick 함수로 설정되어 있으므로, 해당 함수 내부의 코드가 실행된다. 이 코드는 setCount(count + 1)을 호출하여 count 상태변수를 증가시킨다. 그런 다음, 새로운 count 값이 각 버튼의 props로 전달되어 모든 버튼이 새로운 값을 보여준다. 이것을 '상태 끌어올리기(lifting state up)'이라 한다. 상태를 올려 컴포넌트 간의 상태를 공유하였다. 

 

'JS > React' 카테고리의 다른 글

6. React 프로젝트 만들기  (0) 2023.05.22
5. React?  (0) 2023.05.21
4. Node.js  (0) 2023.05.21
3. React dev - Tic Tac Toe 게임 만들기  (0) 2023.05.12
1. React Quick Start - React.dev 정리  (0) 2023.05.08