본문 바로가기

005. [코딩애플] [part1] 버튼에 기능개발을 해보자 & 리액트 state변경하는 법

codeConnection 2024. 5. 21.

간단한 팁

터미널 Warning(노란색) 지우기.

Error(빨간색)은 코드 작동 불가이기 때문에 중요하나, Warning은 변수를 선언해놓고 쓰는 곳이 없다든지, 이런 사항에 대해서 알려주는 기능이다. 도움은 될 수 있으나, 이것 때문에 터미널이 복잡하다면,

코드 최상단에 아래 내용을 붙여 넣는다.

/* eslint-disable */

좋아요 버튼 만들기

버튼 레이아웃 만들기. 이모지로 만들었다.

function App() {
    let [ title, updateTitle ] = useState(
        [
            '가을 남자 코트 추천',
            '강남 우동 맛집',
            '오늘의 일기 예보'
        ]
    );


    return (
        <h2>
            { title[0] }
            <span>
                👍
            </span>
            0
        </h2>
    );
}

계속 바뀔 것 같은 값 state로 담기

좋아요 횟수가 계속 변하는 내용 같다. -> state로 담으면 될 것 같다.

let [ thumb, updateThumbUp ] = useState(0);

// 좋아요 수의 초기값을 0으로 설정

좋아요 버튼(이모지)이 있는 span 태그에 onclick 속성을 달아준다.

기존 html에서는 onclick으로 사용했지만 jsx에서는 onClick으로 표기하여 camelCase로 표기한다.

onClick 내부에는 함수만 올 수 있다.

    return (
        <h2>
            { title[0] }
            <span onClick={버튼을 누르면 좋아요 수가 누적되어 증가되는 함수}>
                👍
            </span>
            0
        </h2>
    );
    return (
        <h2>
            { title[0] }
            <span onClick={() => {thumb + 1}}>
                👍
            </span>
            0
        </h2>
    );

위와 같이 인라인 함수로 지정해도 되고, 함수는 외부에서 선언하고 함수 호출만 해도 된다. 본인은 후자가 가독성이 좋은 것 같아 후자로 하겠다.

function App() {
    let [ title, updateTitle ] = useState(
        [
            '가을 남자 코트 추천',
            '강남 우동 맛집',
            '오늘의 일기 예보'
        ]
    );
    let [ thumb, updateThumbUp ] = useState(0);

    return (
        <h2>
            { title[0] }
            <span>
                👍
            </span>
            0
        </h2>
    );
}

여기서 state의 값을 변경하는 함수에 대한 개념, 즉 useState를 하면서 구조 분해 할당 했을 때 두번째 인자로 넣었던 b의 역할이 등장한다.

state의 상태를 바꾸는 함수

let [a, b] = useState('hi');

이런 함수가 있다고 했을 때, auseState의 값 그 자체, 즉 hi이고, buseState의 값을 바꾸는 함수를 의미한다고 했다.

작명을 할 땐 b 이렇게 하면 안 되고, 사용할 함수명을 적어주면 된다.

let [ thumbUp, updateThumbUp ] = useState(0);

let [ thumb, setThumbUp ] = useState(0);

function handleThumbUp() {
    setThumbUp(thumbUp + 1);
}

상태를 변경하는 함수를 짜는 것이 다소 어려운데,

리액트에서 상태를 변경하는 함수에 대한 명명 규칙이 따로 있다. 일반적으로 사용하는 함수들과 구분하여야 한다.

setThumbUp이라고 useState을 구조 분해 할당할 때 useState의 상태를 변경하는 함수로 명명했다.

함수의 내용 자체는 없지만, 이 이름으로 함수를 다시 선언해서 코드 블럭을 작성하는 것이 아니다.

즉 위 상태로 setThumbUp(3)이라고 함수를 호출하면, useState의 상태가 초기값 0에서 3이 되는 것이다. 이 자체가 state의 상태를 바꾸는 함수다.

즉, 우리가 하고 싶은 것은 좋아요 버튼을 누를 때마다 state의 값, 정확히는 thumbUp이라고 명명한 state의 값을 초기값 0에서 바꾸고 싶은 것이다.

이렇게 값을 바꾸고 싶을 때는 상태 변경 함수에서 최초 명명한 setThumbUp을 이용하여야 한다.

그런데 우리가 하고 싶은 것은 단순히 초기값만 바꾸는 게 아니라 좋아요 버튼을 누르면 초기값에서 +1 씩 더하는 액션이 필요한 것이기 때문에 handleThumbUp이라는 함수를 다시 하나 만들어 준 것이다.

그리고 return문 내부의 jsx에서는 이를 onClick으로 호출하면 된다.

function App() {
    let [ title, updateTitle ] = useState(
        [
            '가을 남자 코트 추천',
            '강남 우동 맛집',
            '오늘의 일기 예보'
        ]
    );
    let [ thumb, setThumbUp ] = useState(0);
    function handleThumbUp() {
        setThumbUp(thumbUp + 1);
    }

    return (
        <h2>
            { title[0] }
            <span onClick={handleThumbUp}>
                👍
            </span>
            0
        </h2>
    );
}

그런데 여기서 또 헷갈리는 개념이, onClick으로 함수를 불러올 때 기존 html에서는 아래와 같이 작성을 하였었는데

<span onclick="handleThumbUp()"></span>

jsx에서는 따옴표 대신 중괄호로 감싸고 매개 변수를 받지 않는다는 것.

<span onClick={handleThumbUp}></span>

정리

  1. 클릭할 때 무언가 실행하고 싶다면 onClick={함수}로 이벤트 핸들러를 달아서 사용한다. 함수를 호출할 때 소괄호는 넣지 않는다.

  2. state를 변경하려면 state 변경 함수를 이용한다.

    1. state 변경 함수는 자유롭게 명명하되, 기존 함수들과는 다른 컨벤션으로 구분되게 명명하여야 한다.
    2. state 변경 함수는 명명하는 순간 그 자체가 이미 초기값을 지정하는 함수가 되는 것이다
      예를 들어 setThumbUp 으로 설정했다면 setThumbUp(1) 이라고 함수를 호출하면 state의 초기값에서 값이 1로 바뀌게 된다.
    3. 만약 이벤트 핸들러를 통해 어떤 액션이 있을 때 state 값을 변경하는 로직을 추가하고 싶다면 별도의 함수를 선언한다. 그리고 그 함수 코드 블럭에서 setThumbUp(바꿀 로직)을 호출해서 값을 바꾼다.

최종 완성 코드 (CSS는 안 함)

import logo from './logo.svg';
import './App.css';
import { useState } from 'react';

function App() {

  let [title] = useState(
    [
      '남자 코트 추천',
      '강남 우동 맛집',
      '파이썬 독학',
    ]
  );

  let [thumbUp, setThumbUp] = useState(0);

  function handleThumbUp() {
    setThumbUp(thumbUp + 1); // 초기값을 변경하는 함수
    // 최초 0부터 시작해서 1씩 더하는 것.
  }

  return (
    <div className="App">
      <div className="black-nav">
        <div>
          개발 블로그
        </div>
        <div>
          <h1>
            {title[0]}
            <span onClick={handleThumbUp}>
              👍
            </span>
            {thumbUp}
          </h1>
          <span>
            2월 17일 발행
          </span>
          <h1>
            {title[1]}
          </h1>
          <span>
            2월 17일 발행
          </span>
          <h1>
            {title[2]}
          </h1>
          <span>
            2월 17일 발행
          </span>
        </div>
      </div>
    </div>
  );
}

export default App;

댓글