본문 바로가기
React TIL

쉬어가는 TIME - 개인과제 중간점검(?) (feat. 꿀팁)

by 림졍 2024. 11. 9.

 

조금 멍청하게 코딩하는 거 같은 느낌이 들어

작성해보는 몇가지 꿀팁과 기타 등등... 조금 적어보고자 한다

 

11 / 9 - Props Drilling 구현 완료

터미널에서 간단하게 생성하는 법 (VsCode 구우우욷이 들어가지 않아도 되는 방법임)

pwd
cd 파일경로(림졍의 경우 Desktop/React)
yarn create vite 파일명 --template react

 

터미널에서 실행한 결과

 

결과는 어떻게 나오냐구요?

이렇게 뾰로롱 하고 나타난답니다.

폴더 변경 실은 저기서 해도 되긴 함 ㅇㅇ

근데 폴더 열려있는 상태에서 하면 안됨. 매우 곤란.

 

 

개인과제 파일구조

 

개인과제 구현은 대애충 단계별로 나누면 아래와 같다

1단계 props drilling

2단계 context로 관리

3단계 이덕수 (Redux입니다)

 

그래서 일단 1-2단계를 위한 파일구조를 대충 짜본 모습.. (는 정확하게 과제에서 하라는 거 넣으라고 한 부분대로 컴포넌트 나눔..)

 

[구조]

src
├── assets
├── components
│   ├── pokedetails
│   │   └── PoketmonDetail.jsx
│   └── pokedex
│       ├── Dashboard.jsx
│       ├── PoketmonCard.jsx
│       ├── PoketmonList.jsx
├── pages
│   ├── Home.jsx
│   ├── PokeDetails.jsx
│   └── PokeDex.jsx
├── shared
│   └── Router.jsx
├── App.css
├── App.jsx
├── index.css
└── main.jsx

 

이런식으로 props drilling을 한다고 생각하면 된다..

(실은 App.jsx은 세상 깔끔 그 자체였음..)

 

- 깔끔했던 App.jsx

import Router from './shared/Router';

function App() {
  return <Router />;
}

export default App;

 

- 갑자기 더러워진 App.jsx

import { useState } from 'react';
import Router from './shared/Router'

function App() {
  const [selectedPokemons, setSelectedPokemons] = useState([]);

  const addPokemon = (pokemon) => {
    
    if (selectedPokemons.find((p) => p.id === pokemon.id)) {
      alert("이미 선택된 포켓몬입니다.");
      return;
    }
    
    if (selectedPokemons.length >= 6) {
      alert("최대 6개의 포켓몬만 선택할 수 있습니다.");
      return;
    }

    setSelectedPokemons([...selectedPokemons, pokemon]);
  };

  const removePokemon = (pokemon) => {
    setSelectedPokemons(selectedPokemons.filter((p) => p.id !== pokemon.id));
  };

  const resetPokemons = () => {
    setSelectedPokemons([]);
  };
  return <Router 
  selectedPokemons={selectedPokemons}
  addPokemon={addPokemon}
  removePokemon={removePokemon}
  resetPokemons={resetPokemons}
  />;
}

export default App;

 

이렇게 된 이유요? ...욕심부리다가 그랬습니다.

이거 해결하려다가 코드 제대로 한번 엎은 바보됨..ㅜ

 

로컬스토리지하면 context에서 더 지저분해진다는 소리를 듣고..

그냥 하는거 지금 고생해놓지뭐 하고... 노는 것을 포기(?)하고 코딩을 했던 me였다고 한다.

 

그렇게 조금 어리바리까면서 헤딩좀 하다가

결국 해냄 ㅜㅡㅜ

 

 

추가) 갑자기 떠버린 경고 메세지 해결법

뭐냐 넌..?

계속 옆에 props validation이 없어졌어요!! 라고 뜨는 오류들이 많이 발생해서

저 빨간 코드가 뭐지... 왜 떴을까.. 하고 물어보니

규칙을 비활성화 하면 된단다... (라고 깡통이 말해줌)

우리는 1번 적용할 예정!

// eslint.config.js
// 위의 코드는 생략...

    rules: {
      ...js.configs.recommended.rules,
      ...react.configs.recommended.rules,
      ...react.configs['jsx-runtime'].rules,
      ...reactHooks.configs.recommended.rules,
      'react/jsx-no-target-blank': 'off',
      'react-refresh/only-export-components': [
        'warn',
        { allowConstantExport: true },
      ],
      "react/prop-types": "off"
    }

 

...이제 context는 내일할거고

자야지

커어어..

 

11 / 10 - Context API 적용 완료

Context 적용을 위해, components 내부 PokemonContext.jsx 파일 추가

파일이 추가된 모습.

 

Fast refresh 경고 메시지 관련 이슈 해결법

 

PokemonContext에 모든 기능을 다 넣었더니...

// PokemonContext.jsx
import { createContext, useContext, useState } from 'react';

const PokemonContext = createContext();

export const PokemonProvider = ({ children }) => {
  const [selectedPokemons, setSelectedPokemons] = useState([]);

  const addPokemon = (pokemon) => {
    if (selectedPokemons.length >= 6) {
      alert("최대 6개의 포켓몬만 선택할 수 있습니다.");
      return;
    }
    if (!selectedPokemons.find((p) => p.id === pokemon.id)) {
      setSelectedPokemons([...selectedPokemons, pokemon]);
    } else {
      alert("이미 선택된 포켓몬입니다.");
    }
  };

  const removePokemon = (pokemon) => {
    setSelectedPokemons(selectedPokemons.filter((p) => p.id !== pokemon.id));
  };

  const resetPokemons = () => {
    setSelectedPokemons([]);
  };

  return (
    <PokemonContext.Provider value={{ selectedPokemons, addPokemon, removePokemon, resetPokemons }}>
      {children}
    </PokemonContext.Provider>
  );
};

export const usePokemonContext = () => {
  return useContext(PokemonContext);
};

 

뭐여 이건;

갑자기 이렇게 당황스러운 경고문이 떠버리게 되었는데..

대충 살펴보니.. PokemonProvider와 usePokemonContext가 동시에 export가 되어서 그럴 것 같은... 찌리릿이 와버린 림졍.

결국 깡통(GPT입니다. 이제 설명 안할거에요.)한테 물어보니

역시.. 저 둘을 나눠서 해줘야 한다고 하더군요.

역시 내 촉이 맞았어.

 

결국 PokemonContext.jsx 를 PokemonProvider.jsx 와 usePokemonContext.js (여기선 js문법만 사용되어서..)로 분할하여

따로 써줬다고 합니다...

그러고 불필요한 파일은 지우고 구조를 조금 다시 바꿔서 수정한 파일구조는

이미지로 보긴 조금 귀찮으니까 대충 보기 편하게 텍스트로 보여드리겠습니다.

src
├── components
│   ├── pokedetails
│   │   └── PokemonDetail.jsx
│   ├── pokedex
│   │   ├── Dashboard.jsx
│   │   ├── PokemonCard.jsx
│   │   └── PokemonList.jsx
├── context
│   ├── PokemonProvider.jsx
│   └── usePokemonContext.js
├── datas
│   └── data.js
├── pages
│   ├── Home.jsx
│   ├── PokeDetails.jsx
│   └── PokeDex.jsx
├── shared
│   ├── GlobalStyles.jsx
│   └── Router.jsx
├── App.jsx
└── main.jsx

 

이제 남은건 이덕수.

(아 오디오 개싫은데 박읍읍이 시킬듯;)

여튼 나머지는 내일의 림졍에게 맡기고 자야겠다

커어어어...

쿨쿨..

728x90
반응형

'React TIL' 카테고리의 다른 글

[React] Day_38 데일리 정리  (4) 2024.11.11
[React] Day_37 데일리 정리  (2) 2024.11.10
[React] Day_36 데일리 정리  (4) 2024.11.08
[React] Day_35 데일리 정리  (0) 2024.11.07
[React] Day_34 데일리 정리  (1) 2024.11.06