개발자 박가나
[241108 TIL] 본캠프 28일차 ('포켓몬 도감 만들기' 프로젝트 3일차) 본문
📌 오늘의 TIL
|
[포켓몬 도감] 프로젝트
코드 리팩토링. props drilling 방식을 Context API 방식으로 변경
Context API를 이용해서 state를 전역적으로 관리해준다.
/* context/PokemonContext.js */
import { createContext } from 'react';
export const PokemonContext = createContext(null);
/* Dashboard.js */
import { useContext } from 'react';
import { PokemonContext } from '../context/PokemonContext';
export default function Dashboard() {
const { myPokemons } = useContext(PokemonContext);
return (
<Container>
<Title>나만의 포켓몬</Title>
<BallContainer>
{myPokemons.map((pokemon) => {
return <PokemonCard key={pokemon.id} type={'my'} pokemon={pokemon} />;
})}
{[...Array(6 - myPokemons.length)].map(() => {
return <PokemonBall key={uuid()} />;
})}
</BallContainer>
</Container>
);
}
/* PokemonCard.js */
import { useContext } from 'react';
import { PokemonContext } from '../context/PokemonContext';
export default function PokemonCard({ type = 'list', pokemon }) {
const { handleAdd, handleDelete } = useContext(PokemonContext);
/* 카드 내 버튼 클릭 이벤트 */
const handleClick = (e) => {
// 이벤트 버블링 방지
e.stopPropagation();
type === 'list' ? handleAdd(pokemon) : handleDelete(pokemon);
};
return (
<Container onClick={() => navigate(`/detail/${pokemon.id}`)}>
<Character src={pokemon.img_url} />
<Name>{pokemon.korean_name}</Name>
<Description>No. {String(pokemon.id).padStart(3, '0')}</Description>
<Button type="sub" bgcolor="red" label={type === 'list' ? '추가' : '삭제'} handleClick={handleClick} />
</Container>
);
}
기능 구현. 상세 정보 페이지에서 나만의 포켓몬 추가 및 삭제하기
Dex 페이지 뿐만 아니라 Detail 페이지에서도 나만의 포켓몬 추가 및 삭제가 가능하게 해준다.
/* Detail.js */
import { useNavigate, useParams } from 'react-router-dom';
import styled from 'styled-components';
import Button from '../components/Button';
import MOCK_DATA from '../Data';
import { useContext, useEffect, useState } from 'react';
import { PokemonContext } from '../context/PokemonContext';
export default function Detail() {
const { myPokemons, handleAdd, handleDelete } = useContext(PokemonContext);
const [label, setLabel] = useState('');
useEffect(() => {
const isAdd = myPokemons.length && !!myPokemons.find((item) => item.id === Number(param.id));
setLabel(isAdd ? '삭제' : '추가');
}, [myPokemons, param.id]);
return (
<>
{pokemon && (
<Wrap>
<Character src={pokemon.img_url} alt="character" />
<Name>{pokemon.korean_name}</Name>
<Description>
타입 :{' '}
{pokemon.types.map((type, index) => {
return index < pokemon.types.length - 1 ? `${type}, ` : type;
})}
</Description>
<Description>{pokemon.description}</Description>
<ButtonContainer>
<Button bgcolor="red" label={label} handleClick={() => (label === '추가' ? handleAdd(pokemon) : handleDelete(pokemon))} />
<Button bgcolor="black" label="뒤로 가기" handleClick={() => navigate('/dex')} />
</ButtonContainer>
</Wrap>
)}
</>
);
}
'내일배움캠프' 카테고리의 다른 글
[241112 TIL] 본캠프 30일차 (0) | 2024.11.12 |
---|---|
[241111 TIL] 본캠프 29일차 ('포켓몬 도감 만들기' 프로젝트 4일차) (0) | 2024.11.11 |
[241107 TIL] 본캠프 27일차 ('포켓몬 도감 만들기' 프로젝트 2일차) (0) | 2024.11.07 |
[241106 TIL] 본캠프 26일차 ('포켓몬 도감 만들기' 프로젝트 1일차) (0) | 2024.11.06 |
[241105 TIL] 본캠프 25일차 (1) | 2024.11.05 |