Recent Posts
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
관리 메뉴

개발자 박가나

[241111 TIL] 본캠프 29일차 ('포켓몬 도감 만들기' 프로젝트 4일차) 본문

내일배움캠프

[241111 TIL] 본캠프 29일차 ('포켓몬 도감 만들기' 프로젝트 4일차)

gnchoco97 2024. 11. 11. 20:02

  📌 오늘의 TIL
  • [포켓몬 도감] 프로젝트

 

 

 [포켓몬 도감] 프로젝트 

코드 리팩토링. Context API 방식을 RTK 방식으로 변경

Redux Toolkit을 이용해서 좀 더 효율적으로 전역 상태 관리를 해준다.

/* redux-toolkit/config/configStore.js */

import { configureStore } from '@reduxjs/toolkit';
import pokemon from '../slices/pokemonSlice';

const store = configureStore({
    reducer: {
        pokemon
    }
});

export default store;
/* redux-toolkit/slices/pokemonSlice.js */

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
    myPokemons: []
};

const pokemonSlice = createSlice({
    name: 'pokemon',
    initialState,
    reducers: {
        /* 나만의 포켓몬 추가 */
        addPokemon: (state, action) => {
            state.myPokemons = [...state.myPokemons, action.payload.pokemon];
        },

        /* 나만의 포켓몬 삭제 */
        deletePokemon: (state, action) => {
            state.myPokemons = [...state.myPokemons.filter((pokemon) => pokemon.id !== action.payload.pokemon.id)];
        }
    }
});

export const { addPokemon, deletePokemon } = pokemonSlice.actions;
export default pokemonSlice.reducer;
/* Dashboard.js */

import { useSelector } from 'react-redux';

export default function Dashboard() {
    const { myPokemons } = useSelector((state) => state.pokemon);

    return (
        ...
    );
}
/* PokemonCard.js */

import { useDispatch, useSelector } from 'react-redux';
import { addPokemon, deletePokemon } from '../redux-toolkit/slices/pokemonSlice';
import { CheckMyPokemons } from '../functions/checkMyPokemons';

export default function PokemonCard({ type = 'list', pokemon }) {
    const dispatch = useDispatch();

    const { myPokemons } = useSelector((state) => state.pokemon);

    /* 카드 내 버튼 클릭 이벤트 */
    const handleClick = (e) => {
        // 이벤트 버블링 방지
        e.stopPropagation();

        type === 'list' ? CheckMyPokemons(myPokemons, pokemon) && dispatch(addPokemon({ pokemon })) : dispatch(deletePokemon({ pokemon }));
    };

    return (
        ...
    );
}

 

 

오류 해결. Vercel 배포 시 이미지 파일의 url을 읽어오지 못함

 

기능 구현을 완료하고 Vercel로 배포를 했는데, 로컬에서는 문제없이 읽어오던 이미지 파일들을 Vercel에서는 읽어오지 못하는 문제가 발생했고 console에도 404 에러라고 나올 뿐이었다. 구글링을 해보니 Vercel에 배포 시 로컬에서의 폴더 및 파일 구조처럼 유지되지 않는 경우도 있기 때문에 상대 경로로 지정된 이미지 파일을 읽지 못할 수도 있다고 했다.

 

경로를 직접 작성하지 않고 이미지 파일을 import해서 사용함으로써 문제를 해결할 수 있었다.

/* Home.js */

import { useNavigate } from 'react-router-dom';
import Button from '../components/Button';
import LogoImage from '../assets/logo.png';

export default function Home() {
    const navigate = useNavigate();

    return (
        <Wrap>
            <Logo src={LogoImage} alt="logo" />
            <Button bgcolor="red" label="포켓몬 도감 시작하기" handleClick={() => navigate('/dex')} />
        </Wrap>
    );
}