useState()를 이해하기 위한 좋아요 버튼 만들기

Louis·2023년 11월 30일
1
post-thumbnail

안녕하세요!!

useState()에 대해 어느 정도 알고 있다고 생각했지만 알고만 있었지 그 것을 어떻게 활용하는지에 대해 전혀 알지 못 하고 있었습니다...!! 그래서 정말 심각성을 알게 되었고... 차근차근하지만 빠르게 공부를 하려고 생각을 했고 오늘 베이직반에 배운 내용을 토대로 정리하기 위해 이렇게 포스팅합니다..!

그럼 바로 시작해보겠습니다!

오늘은 useState() 를 이해하기 좋은 좋아요 버튼을 만들어보겠습니다!

튜터님께서 정말 친절하시게도 기본 코드를 제공해주셨습니다

풀어야할 코드

// App.jsx
import { useState } from "react";
import { nanoid } from "nanoid"; // nanoid import

function App() {
  // 각 데이터에 고유한 id 부여
  const [todos, setTodos] = useState([
    { id: nanoid(), content: "리액트 공부하기1" },
    { id: nanoid(), content: "리액트 공부하기2" },
    { id: nanoid(), content: "리액트 공부하기3" },
    { id: nanoid(), content: "리액트 공부하기4" },
  ]);
  return (
    <>
      {todos.map((todo, i) => {
        return (
          // key에 nanoid 적용
          <div key={todo.id}>
            <span>{todo.content}</span>
            <button
              onClick={() => {
                setTodos(todos.filter((td) => td.id !== todo.id));
              }}
            >
              삭제
            </button>
          </div>
        );
      })}
    </>
  );
}

export default App;

해당 코드입니다 우리는 여기서 좋아요 버튼을 만들고
클릭했을 때 좋아요 개수가 늘어나야합니다
하지만 여기서 중요한 것은
내가 누를 특정 버튼만 좋아요 개수가 증가해야된다는 것입니다

하나씩 뜯어보기

const [todos, setTodos] = useState([
    { id: nanoid(), content: "리액트 공부하기1" },
    { id: nanoid(), content: "리액트 공부하기2" },
    { id: nanoid(), content: "리액트 공부하기3" },
    { id: nanoid(), content: "리액트 공부하기4" },
  ]);

해당 코드는 useState() 를 이용한 코드입니다

todos의 기본 값을

[
    { id: nanoid(), content: "리액트 공부하기1" },
    { id: nanoid(), content: "리액트 공부하기2" },
    { id: nanoid(), content: "리액트 공부하기3" },
    { id: nanoid(), content: "리액트 공부하기4" },
  ]

배열로 넣어주었습니다
그 이유는 여러가지의 내용이 들어가기 때문인데요
여러가지가 들어가야되면 배열로 준비해주는 것이 가장 효율적입니다
그리고 우리가 누르는 특정 버튼을 구분해주기 위해서 id 객체에 넣어주게 됩니다


return (
    <>
      {todos.map((todo, i) => {
        return (
          // key에 nanoid 적용
          <div key={todo.id}>
            <span>{todo.content}</span>
            <button
              onClick={() => {
                setTodos(todos.filter((td) => td.id !== todo.id));
              }}
            >
              삭제
            </button>
          </div>
        );
      })}
    </>
  );

다음은 return 부분입니다 현재는 좋아요 버튼이 없는 것 같군요
네 맞습니다 현재는 좋아요 버튼 없이 삭제 부분만 존재하고 있습니다

여기는 map 함수가 들어가게 됩니다 map의 기본 구조는 변수명.map(()=>{}) 입니다

(todo, i)는 현재 인자 값으로 해석할 수 있습니다 useState() 기본값 중에서 id 값을 챙기겠다 라는 뜻입니다

그 다음 {todo.id} 코드는 기본값으로 선언해준 id의 value 값으로 div를 꾸리겠다 라는 듯이 되고

{todo.content} 코드는 기본값으로 선언해준 content의 value 값을 넣어주겠다는 뜻입니다

그 다음 버튼이죠 버튼은 우리가 클릭을 했을 때 filter로 걸러주는 작업을 시작하는데 td는 인자 값이기 때문에 아무런 값을 넣고 그 다음 누른 id 값이 todo.id 값이랑 다른 것들만 나열해주겠다 라는 뜻을 갖고 있습니다


정답 코드

import { useState } from "react";
import { nanoid } from "nanoid"; // nanoid import

function LikeBtn() {
	// 각 데이터에 고유한 id 부여
	const [todos, setTodos] = useState([
		{ id: nanoid(), content: "리액트 공부하기1", like: 0 },
		{ id: nanoid(), content: "리액트 공부하기2", like: 0 },
		{ id: nanoid(), content: "리액트 공부하기3", like: 0 },
		{ id: nanoid(), content: "리액트 공부하기4", like: 0 },
	]);
	return (
		<>
			{todos.map((todo, i) => {
				return (
					// key에 nanoid 적용
					<div key={todo.id}>
						<span>{todo.content}</span>
						<button
							onClick={() => {
								setTodos(todos.filter((td) => td.id !== todo.id));
							}}
						>
							삭제
						</button>
						<button
							onClick={() => {
								const likechagetodos = todos.map((btn) => {
									if (btn.id === todo.id) {
										return {
											...btn,
											like: btn.like + 1,
										};
									} else {
										return btn;
									}
								});
								setTodos(likechagetodos);
							}}
						>
							좋아요개수: {todo.like}
						</button>
					</div>
				);
			})}
		</>
	);
}

export default LikeBtn;

하나씩 뜯어보기

이렇게 코드가 작성이 되는데 위에서 해석한 내용을 제외하고 추가한 코드들에 대해 해석을 진행해보겠습니다

const [todos, setTodos] = useState([
		{ id: nanoid(), content: "리액트 공부하기1", like: 0 },
		{ id: nanoid(), content: "리액트 공부하기2", like: 0 },
		{ id: nanoid(), content: "리액트 공부하기3", like: 0 },
		{ id: nanoid(), content: "리액트 공부하기4", like: 0 },
	]);

위와 다르게 새로운 Key 값인 like가 추가 되었죠?
이 것은 좋아요의 기본값을 세팅해주기 위함이며 내가 좋아요 버튼을 클릭했을 때
다른 좋아요 버튼도 클릭되는 것을 방지 해주기 위함이라고 생각하시면 좋을 것 같습니다


<button
	onClick={() => {
		const likechagetodos = todos.map((btn) => {
			if (btn.id === todo.id) {
				return {
					...btn,
					like: btn.like + 1,
				};
			} else {
				return btn;
			}
		});
		setTodos(likechagetodos);
	}}
>
	좋아요개수: {todo.like}
</button>

좋아요버튼에 핵심적인 코드라고 생각하시면 좋을 것 같습니다

이번에도 map 함수가 들어가네요
그래서 새롭게 likechagetodos 이름으로 변수를 설정해주고 todos.map(()=>{}) map 함수를 적어두었습니다 이유는 동일하게 4가지를 뽑기 위해서 입니다

거기서 추출한 btn.id 와 todo.id의 값이 같을 경우 기존의 btn 값이 나오고 선택한 버튼에는 btn.like + 1 의 값이 나오게 설정해주었습니다

이 조건이 성립이 되지 않는다면 그냥 btn만 선언이 될 수 있도록 설정해주었습니다

이 내용의 배열들이 setTodos에 들어가게 됩니다

그리고 마지막으로 좋아요개수에는 {todo.like}를 넣어 내가 클릭한 좋아요 값만 보여주게 됩니다


네 오늘은 좋아요 버튼을 제작하면서 useState()에 대해 공부를 해보았는데요

쉽지않았습니다..

당연히 기본인 것을 알기에 더 열심히 하고 정확히 알아야하는 부분이긴 하지만 저도 어쩔 수 업서이 이 부트캠프 진도를 따라가야되는데 두 마리 토끼를 다 잡지 못해서 이것도 안되고 저것도 안되고 하는 상황인 것 같습니다 저는 오랜시간이 걸려도 기본부터 탄탄하게 준비하고 싶은데 부트캠프에도 계획이 있으니깐 또 따라 가야하고..

저 처럼 부트캠프에 대해 고민이 많으신 분들이 계실 것 같은데 제가 9월부터해서 3개월 정도 해본 사람의 느낌점으로는 전공과 비전공은 크게 상관이 없지만 기본기가 없다면 부트캠프에 대해 많이 생각을 해보시는 것이 좋을 것 같습니다

부트캠프를 시작하시려고 하시는 분들은 보통 성인이잖아요? 성인은 하루하루가 소중하게 느껴지실텐데 기본기 없이 부트캠프에 들어가서 저 처럼 이것 저것 하다가 모든 것을 놓치는 것 보다 기본기를 학원을 통해 익힌 다음에 부트캠프에 대해 고민하는 것도 좋은 방법인 것 같습니다

물론! 정말 진도를 잘 따라가서 이해가 금방 되신 분들은 부트캠프 바로 들어가셔도 좋을 것 같긴합니다

저의 이야기가 그렇다는 것이구요 혹시나 저와 상황이 비슷하신 분들이 계실까봐 말씀드립니다..!

저는 현재 많이 고민을 하고 있긴 하지만 부트캠프를 통해 코드의 맛을 보고 추가적으로 학원을 다닌다거나 따로 준비하는 것도 나쁘지는 않겠다 라는 생각이 들어서 현재 그냥 어떻게든 따라가려고 부트캠프를 유지하고 있는 것 같습니다..

말이 주제와 맞지 않게 조금 길어진 것 같습니다..!!

이 부분에 대해서는 따로 포스팅을 통해 남겨보도록 하겠습니다!

그럼 여러분 오늘도 너무 고생많으셨구요 항상 빠이팅이며
우리는 또 행복하자구요!!

profile
디자이너의 코딩 도전👍🏻

0개의 댓글