[React] useState와 객체 데이터를 사용해서 map 함수 작성

HongDuHyeon·2022년 3월 22일
10
post-thumbnail
오랜만에 신발을 구매했다고 하더라도 남아있는 이 공허함은..... 비구조화 할당...?

useState, 객체 데이터, map

이 셋의 삼각관계를 은밀히 알아보겠다... 실제로 사용해보니 놀랍기도 하면서 굉장한 녀석들이었다...(feat.갓민주님)
(감동은 아님. 좀 힘들었음.)

각설하고 시작한다.

useState의 강렬했던 첫인상

전에 간단하게 state에 대해 작성해본 적이 있다. 아 물론 그땐 지금처럼 사용하진 않고 기본적인 지식과
작고 소중한 예제를 하면서 이해를 돕기 위해 적었던 글이 있다.
잠시 참고를 하실분들은 하셔도 됩니다.
작고 소중한 state

아무튼 좀 더 심화과정이고 state의 값이 변경 되기 위한 useState를 배워보는 시간을 가졌다.
처음엔 문법조차 생소했다. 도대체 저건 뭐고 저 문법은 뭐지? 저 괄호엔 도대체 어떤 값을 넣어야하지?
별에 별 생각이 다들었던 것 같다.

const [exampleArray, setExampleArray] = useState([]);

하염없이 구글링하며 몇번 본적이 있었는데 직접 사용하며 오류 더미를 볼때마다 느끼게 된다.
좀 더 공부할걸
여기까지 내가 느꼈던 useState의 첫인상이다.

이제 진짜 시작한다.

useState 란 ?

일단 React-hook은 함수형 컴포넌트에 기능을 추가할 때 사용하는 함수다.
함수형 컴포넌트에서 상태값을 사용할 수 있고 자식요소에 접근 할 수도 있다.
(react-hook에 대해선 심도있게 한번 정리할 예정)

useState는 컴포넌트에서 state값을 추가할 때 사용된다. 함수형 컴포넌트에서는 클래스형 컴포넌트처럼 state를 사용할 수 없어서, hook을 사용해서 state와 같은 기능을 할 수 있도록 만들어줬다.

  • useState 불러오기
import React, { useState } from 'react';
  • useState 선언하기
const [count, setCount] = useState(0);

위에 적었듯 불러와주고 선언해주는걸 떠나서 직접 사용한 예제를 아래 코드에 봐보자

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

return (
	<div>
  		<p>Click Count {count} times !</p>
    	<button onClick={() => setCount(count + 1)}Click Me !!</button>
  	</div>
)

아래에 버튼을 누르게 되면 어떻게 될까 ? 그렇다 count에 숫자가 1씩 올라간다.

왜?

변수의 useState()의 괄호 안에 숫자는 count의 초기값이다. 배열이 들어가게 된다면 ([])이 된다.
그럼 두번째 setCount는 무엇인가? 바로 count를 업데이트 해주는 함수이다. 그래서 예제 버튼을 클릭하게 되면 setCount에서 동작하는 count + 1이 실행이 되고 p태그 안에 있는 count는 증가 하게 되는 것이다.

setCount 비동기로 처리가 된다. 비동기는 응답과 상관없이 다음 동작을 처리하는 방식이다.
비동기로 처리되는 이유는 이 함수가 호출 될때마다 화면을 다시 그리기 때문에 성능에 이슈가 생길 수도 있어서 그렇다.

mock data 객체 데이터 준비

mock data 란 ?

실제 API 에서 받아온 데이터가 아닌 프론트엔드 개발자가 필요에 의해 샘플로 만들어 본 데이터를 말합니다.

지금 쓰는 객체 데이터에선 JSON 파일에다가 내가 만든 mock data를 사용해보겠다.

[
  {
    "id": 1,
    "userId": "duuu.__.hyeon",
    "userFeed": "그래도 sass가 나은 편이지 자바스크립트랑 리액트에 비하면 ",
    "userImg": "https://media.vlpt.us/images/hongduhyeon/post/ebc33b2c-f8c5-4792-9a2f-b1dbc5529372/sass.png?w=768",
    "isLiked": true,
    "userComment": [
      {
        "id": 1,
        "userName": "wecode",
        "content": "Welcome to world best coding bootcamp!",
        "isCommentLiked": true
      },
      {
        "id": 2,
        "userName": "jayPark",
        "content": "Hey.",
        "isCommentLiked": false
      }
    ]
  },
  {
    "id": 2,
    "userId": "duuu.__.kong",
    "userFeed": "자바스크립트 진짜 별로야 특히 해달라는 대로 다해줬는데 안들어가는건 무슨 심보니?",
    "userImg": "https://media.vlpt.us/images/hongduhyeon/post/791da457-a0ee-4bd2-8fd4-7839e678bd86/javascript.png?w=768",
    "isLiked": false,
    "userComment": [
      {
        "id": 1,
        "userName": "wecode",
        "content": "리액트는 지옥이다.",
        "isCommentLiked": true
      },
      {
        "id": 2,
        "userName": "HongDuHyeon",
        "content": "부러질지언정 휘어질 수 없다.",
        "isCommentLiked": false
      }
    ]
  },
  {
    "id": 3,
    "userId": "duuu.__.kong",
    "userFeed": "리액트는 할말이 없다. 차라리 날 죽여라 리액트",
    "userImg": "https://media.vlpt.us/images/hongduhyeon/post/ee1b7bfc-29fc-40cc-8226-52eb4996207b/react.png?w=768",
    "isLiked": false,
    "userComment": [
      {
        "id": 1,
        "userName": "wecodeaoisdjo",
        "content": "3번째 컨텐츠",
        "isCommentLiked": true
      },
      {
        "id": 2,
        "userName": "HongDuHyeon",
        "content": "휘어진 것 같다.",
        "isCommentLiked": false
      }
    ]
  }
]
  • id : 각 리스트의 id값
  • userId : 유저 개인의 아이디값
  • userFeed : 유저의 게시글 본문
  • userImg : 유저가 업로드한 게시글 사진
  • isLiked : 좋아요 (boolean 값)
  • userComment : 유저들이 남긴 댓글
    • userName: 댓글 남긴 유저
    • content : 유저가 남긴 댓글
    • isCommentLiked: 현재 댓글의 좋아요 상태

가장 크게 감싸주고 있는 대괄호를 기준으로 객체 타입으로 중괄호가 들어가고 배열을 선언해줄수도 있다. 이제 이렇게 넣은 데이터를 map을 통해서 한번 사용해보자.

map()으로 갖고 있는 객체 데이터만큼 나타내기

지옥에서 돌아온 javascript - map 정리
먼저 내가 실제로 하고 있는 작업물에 map을 사용하는데 굉장히 괴로운 상황이 많이 오갔다.

작성할 코드를 먼저 설명하면 위에서 만든 mock 데이터에 들어가는 값들을 sns 피드처럼 뿌려주는 역할을 하는 객체들을 내가 미리 스타일을 준 위치에 각각 뿌려주는 작업을 해야했다.
하지만 react에서의 map을 사용해는게 처음이라 많이 헷갈렸다.

  • 먼저 useEffect로 fetch 함수를 써서 데이터를 불러온다.
const Main = () => {
	const [feedArr, setFeedArr] = useState([]);
  	useEffect(() => {
    	fetch('http://localhost:3000/data/commentData.json', {
     		method: 'GET',
    	})
      	.then(res => res.json())
      	.then(data => {
        	setFeedArr(data);
      	});
	}, []);
}
  • return 문안에 map을 작성해서 데이터의 갯수만큼 화면에 뿌려주는 map함수를 작성한다.
  return (
    <div className="main">
      <Nav />
      <div className="container">
        <div className="feeds">
          {feedArr.map(list => {
            return <Feed key={list.id} {...list} />;
          })}
        </div>
        <Aside />
      </div>
    </div>
  );

위에서 데이터를 불러오는 과정에서 데이터를 setFeedArr(data)로 불러왔기 때문에 지금 데이터는 객체 형태로
feedArr에 들어있는 상태이다.

그리고 들어있는 데이터를 먼저 초기값으로 map()함수를 사용해서 뿌려준다.

참고로 여기서 key값을 써주지 않으면 고유의 키값을 사용해야 된다는 오류를 만나게 되는데
그건 React - map 함수 적용시 key props를 부여하는 이유 여기서 확인해보면 그 이유를 알 수 있다.

그리고 spread 연산자를 사용해서 {...list}로 이전에 갖고 있던 객체 데이터를 props를 통해 Feed 컴포넌트로 전달해줬다.

여기서 되게 막혔던게 ...list를 왜 써야하는지 잘 이해가 안되서 구글링을 2시간 동안이나 했다... 구글링도 실력

const Feed = ({ userId, userFeed, userComment, userImg }) => {
	
}

기존 javascript에선 구조 분해 할당을 사용해보긴 했지만 직접 실제로 필요로 인해 사용해본건 이번이 처음이다.
구조 분해 할당을 사용해서 작성해준 코드를 보면 props값이 없을 것이다. 객체 데이터의 key값을 바로 받아주면 props.를 생략할 수 있다는 장점이 있고,

// bad
const Feed = ( userId, userFeed, userComment, userImg )

// good
const Feed = ({ userId, userFeed, userComment, userImg })

객체 데이터여서 일반 괄호안에 중괄호를 한번 더 써줘야한다 !!!!!!! <- 이거 진짜 중요함.(진지 x 100)

그리고 나서 userComment를 제외한 나머지 값들은 {userId},{userFeed} 이렇게 적어줘도 되지만
배열로 들어온 userComment, 즉 아까 작성한 유저가 남긴 댓글들은 그 안에서 또 배열로 들어오기도 하고 그 안에 데이터가 갖고 있는 만큼 보여줘야해서 map을 써야한다.

여기서 알고 가야할 점은 map을 사용해야 한다는 점이다. 그럼 뭐다?

useState로 배열을 하나 만들어주자 !

라는 결과가 나온다.

const [commentArray, setComentArray] = useState(userComment);

이렇게 props로 들어온 배열을 잡아주면 commentArray로 또 다시 한번 map을 돌려서 갖고 있는 댓글만큼 뿌려줄 수도 있고 사용에 용이하다.

느낀점

기존에 javascript, jQuery에서 한번도 사용해보지 않았던 다양한 기술들을 React에서 사용 해보는 것 같다. 아직까지 과거에 많이 사용했던 jQuery만큼 친숙하거나 익숙치 않지만 이번에 굉장히 많은 삽질, 고통과 번뇌 속에서 개발을 진행하다보니 나름 성장한 느낌을 받았다.
부러질지언정 휘어질 수 없다.🔥

profile
마음이 시키는 프론트엔드.. RN과 IOS를 곁들인..

4개의 댓글

comment-user-thumbnail
2022년 3월 25일

설명을 잘해주셔서 이해가 쏙쏙가요 ☺️👍

1개의 답글
comment-user-thumbnail
2022년 5월 26일

안녕하세용 설명을 너무 잘해주셔서 이해가 단번에 되네요~
근데 마지막에 commentArray는 Feed안에서 새로 선언해주고 그안에서 map으로 돌려야 하는거죠?

1개의 답글