
위와 같은 간단한 블로그 예제
좋아요를 눌렀을 때 각 게시글에 따라 좋아요가 각각 올라가게 하라는 과제를 받았다.
import { useState } from 'react';
import './App.css';
function App() {
let nickName = "kglim";
let [title, setTitle] = useState(['혜화 갈비 맛집', '홍대 라멘', '강남 소주 맛집']);
let [like, setLike] = useState([0, 0, 0]);
let [day, setDay] = useState(['2월 11일', '8월 18일', '12월 26일'])
let [count, setCount] = useState(10);
function change(){
setLike(like + 1);
}
return (
<div className="App">
<div onClick={()=>{
setCount(count + 1);
console.log(count)
}}>안녕</div>
<header>
<div className='nav'>나의 소소한 일상 블로그</div>
<p>{nickName}님 어서오세요</p>
<a href='https://cafe.naver.com/kosait' rel='noopener noreferrer' target="_blank">DAEBO KNOWLEDEGE CUBE</a>
</header>
{title.map((item, index) =>
{return <>
<div className='list'>
<h4>{item} <span onClick={() => {let copy = [...like]; copy[index]++; setLike(copy)}}>👍</span>{like[index]}</h4>
</div>
<p>{day[index]}</p>
</>})}
</div>
);
}
export default App;
기존의 like는 배열이 아닌 단순한 숫자 변수로 선언돼 있었다
이를 title과 같은 length를 가진 [0, 0, 0]라는 배열 state로 바꾸어주고
{title.map((item, index) =>
{return <>
<div className='list'>
<h4>{item} <span onClick={() => {let copy = [...like]; copy[index]++; setLike(copy)}}>👍</span>{like[index]}</h4>
</div>
<p>{day[index]}</p>
</>})}
위와 같이 map함수를 사용해 각 좋아요를 바꿔준다.
여기서 setLike를 해줄 때 복사를 사용해주는 이유는 setLike에는 배열의 값이 들어가야 하기 때문이다
따라서 단순히 몇 번째 순서의 값을 바꿀 수는 없고, [0, 1, 0]과 같이 값이 바뀐 배열을 넣어주어야 한다.
*스프레드 연산자를 사용하는 이유?
그를 위해 배열을 복사할 때, let copy = like와 같이 복사하면
주소값을 복사하기 때문에 copy의 값을 바꿀 때 like의 값도 같이 바뀐다.
따라서 리액트는 값이 바뀌었다는 것을 인지하지 못해 렌더링이 일어나지 않는다.
따라서 스프레드 연산자를 사용해 주소값이 다르고 값이 같은 배열을 만들어주는 것이다.

이렇게 하면 각각의 좋아요가 반영된다~!
'개발' 카테고리의 다른 글
리액트 3일차 : useNavigate, react-route-dom (1) | 2022.12.28 |
---|---|
리액트 2일차 (0) | 2022.12.27 |
스프링부트 시작하기 (0) | 2022.08.23 |
210829 트위터 클론코딩 중 메모 (0) | 2021.08.29 |
210828 트위터 클론코딩 중 메모 (0) | 2021.08.29 |