ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

์ด์ „ ๊ธ€์—์„œ RTK์˜ ์ •์˜์™€ ์„ธํŒ…ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •๋ฆฌํ–ˆ๋‹ค.

https://coco910.tistory.com/79

 

[Pokemon PJ_Day 4] RTK (1) - setting

ํ•„์ˆ˜ ๊ณผ์ œ๋ฅผ ๋งˆ์น˜๊ณ  ๋„์ „ ๊ณผ์ œ์ธ RTK๋ฅผ ์ง„ํ–‰ํ•˜์˜€๋‹ค. Context API๋ฅผ ์‚ฌ์šฉํ•œ ๋กœ์ง์—์„œ RTK๋กœ ๋ฐ”๊พธ๋ ค๋‹ˆ ํ—ท๊ฐˆ๋ฆฌ๋Š” ๋ถ€๋ถ„์ด ๋งŽ์•˜๋‹ค.ํฌ๊ฒŒ RTK๋ฅผ ์„ธํŒ…ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์ •๋ฆฌํ•ด๋ณด๊ฒ ๋‹ค.์ด๋ฒˆ ๊ธ€์—

coco910.tistory.com

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•!

 


 

RTK use

 

๐Ÿ“Redux 2๊ฐ€์ง€ ํ•ต์‹ฌ ๊ฐœ๋… : useSelector, useDispatch

  • useSelector : ํ˜„์žฌ state์˜ ๊ฐ’์„ ์กฐํšŒ
  • useDispatch : state์˜ ๊ฐ’์„ ์ถ”๊ฐ€, ์‚ญ์ œ, ์ˆ˜์ •

 

๐Ÿ“์ตœ์ข… ๋ชฉํ‘œ:

[dispatch์— action ๊ฐ์ฒด๋ฅผ ๋‹ด์•„์„œ reducer๋ฅผ ํ†ตํ•ด store์— ๋ณ€๊ฒฝ๋œ ๊ฐ’ ์ „๋‹ฌํ•˜๊ธฐ]

 

 

๐Ÿ“์‚ฌ์šฉ ํ๋ฆ„

1. ์ดˆ๊ธฐ๊ฐ’ ์„ค์ •
2. createSlice ์ •์˜
3. reducer ์ •์˜
   3-1. reducer ๊ตฌ์„ฑ
4. action ๊ฐ์ฒด๋ฅผ ์‹ค์ œ ์‚ฌ์šฉํ•˜๋Š” ๊ณณ์— ์ ์šฉ
   4-1. dispatch๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ •์˜
   4-2. action์ด ์ผ์–ด๋‚˜๋Š” ๋ฒ„ํŠผ์— onClick ์ˆ˜์ •
5. useSelector๋กœ ํ˜„์žฌ state ๊ฐ’ ์กฐํšŒ

 

1. ์ดˆ๊ธฐ๊ฐ’ ์„ค์ •

์šฐ์„  slice์— ์ •์˜ํ•œ ์ดˆ๊ธฐ๊ฐ’์€ ์ด์ „์— ์ž‘์„ฑํ•œ useState์˜ ์ดˆ๊ธฐ๊ฐ’๊ณผ ๋™์ผํ•˜๋‹ค.

๋‚˜๋Š” [ ] ๋นˆ ๋ฐฐ์—ด๋กœ ์ง€์ •ํ•˜์—ฌ ๋“ค์–ด์˜ค๋Š” ๊ฐ’์„ ๊ฐ์ฒด๋กœ ๋‹ด์•„์ฃผ๊ณ  ์žˆ์—ˆ๋‹ค.

const initialState = [];

 

2. createSlice ์ •์˜

slice๋Š” name๊ณผ initialState, reducer๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค.

๊ทธ ์ค‘ reducer๋Š” ์–ด๋–ค ์•ก์…˜์„ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•  ์ง€ ์ •์˜ํ•ด ๋‘๋Š” ํ•จ์ˆ˜์ด๋‹ค.

const monSlice = createSlice({
  name: "setMyPokemon",
  initialState,
  reducers:{},
});

 

 

3. reducer ์ •์˜

๋ฆฌ๋“€์„œ๋Š” state์™€ action์„ ์ธ์ž๋กœ ๊ฐ€์ง€๋ฉฐ state๋ฅผ ์–ด๋–ป๊ฒŒ ๋ณ€๋™์‹œํ‚ฌ์ง€ ํ•จ์ˆ˜๋กœ ํ‘œํ˜„ํ•œ๋‹ค.

reducers: {
	addPokemon: () => {},
    deletePokemon: () => {},
};

 

   3-1. reducer ๊ตฌ์„ฑ

๋ณดํ†ต state ๊ฐ์ฒด ๋‚ด๋ถ€ ์š”์†Œ์˜ ๊ฐ’์„ ์ƒˆ๋กœ์šด ๊ฐ’(action.payload)์œผ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

ํ•˜์ง€๋งŒ, ๋‚˜๋Š” state๊ฐ€ [ ]์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐ์—ด ์•ˆ์— 1๏ธโƒฃ์ƒˆ๋กœ์šด ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ 2๏ธโƒฃ์ƒˆ๋กœ์šด ๋ฐฐ์—ด๋กœ ์žฌ์ •์˜ ํ•ด์•ผํ•œ๋‹ค.

 

1๏ธโƒฃ์ƒˆ๋กœ์šด ๊ฐ’์„ ์ถ”๊ฐ€(์„ ํƒ)

  • immer์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•œ state ๋ณ€๊ฒฝ์€ ํ—ˆ์šฉํ•œ๋‹ค.
state.push(action.payload);

 

2๏ธโƒฃ์ƒˆ๋กœ์šด ๋ฐฐ์—ด๋กœ ์žฌ์ •์˜

  • ์žฌ์ •์˜ํ•˜์—ฌ state์˜ ์ฃผ์†Œ๊ฐ’ ๋ณ€๊ฒฝ(setState์™€ ๊ฐ™์€ ์—ญํ• )
return [...state, action.payload];

 

[์ตœ์ข… reducer]

reducers: {
    addPokemon: (state, action) => {
      state.push(action.payload);
    },
    deletePokemon: (state, action) => {
      state.pop(action.payload);
    },
  },

 

 

4. action ๊ฐ์ฒด๋ฅผ ์‹ค์ œ ์‚ฌ์šฉํ•˜๋Š” ๊ณณ์— ์ ์šฉํ•˜๊ธฐ

   4-1. PokemonCard.jsx ๋กœ์ง ์ƒ๋‹จ์— dispatch๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ •์˜(import ํ•„์ˆ˜)

 const dispatch = useDispatch();

 

   4-2. action์ด ์ผ์–ด๋‚˜๋Š” ๋ฒ„ํŠผ์— onClick ์ˆ˜์ •

  • () => {} : dispatch() (=์‹คํ–‰ ๊ฐ’)์ด ์•„๋‹Œ ํ•จ์ˆ˜๋กœ ์‹คํ–‰
  • addPokemon() : ์‚ฌ์šฉํ•˜๋Š” reducer
  • data : payload ๊ฐ’ (์—ฌ๊ธฐ์„œ๋Š” ํฌ์ผ“๋ชฌ ํ•˜๋‚˜์˜ ์ •๋ณด(๊ฐ์ฒด)
 <AddBtn onClick={() => {dispatch(addPokemon(data))}}>์ถ”๊ฐ€</AddBtn>

 

์‚ญ์ œ ๋กœ์ง๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ง„ํ–‰ํ•˜์˜€๋‹ค.

 

5. useSelector๋กœ ํ˜„์žฌ state ๊ฐ’ ์กฐํšŒ

๋‹ค ๊ตฌ์„ฑํ•œ ์ค„ ์•Œ์•˜๋Š”๋ฐ dashboard์—์„œ mapping ํ•˜๋Š” ๋ฐฐ์—ด์ด ์ •์˜๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋–ด๋‹ค.

๊ทธ ๋ฐฐ์—ด์€ myMon์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ state๊ฐ’์ด๋‹ค.

 

ํ˜„์žฌ state ๊ฐ’์„ ์กฐํšŒํ•˜๋Š” useSelector๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜ค๋ฅ˜๋ฅผ ํ•ด๊ฒฐํ–ˆ๋‹ค.(๋กœ์ง์€ ์ตœํ•˜๋‹จ์—)

 

์ด๋กœ์จ RTK๋กœ ๋ฆฌํŒฉํ† ๋ง๋„ ์„ฑ๊ณต!

 

 

 

๐Ÿ“Œ์ตœ์ข… ๋กœ์ง

 

[Store]

import { configureStore } from "@reduxjs/toolkit";
import monSliceReducer from "../slices/setMyPokemonSlice";

export const store = configureStore({
  reducer: {
    setMyPokemon: monSliceReducer,   ๐Ÿ‘‰๐Ÿป๋ฆฌ๋“€์„œ์˜ name: ๋ณ€์ˆ˜(default๋กœ exportํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค ๋ณ€์ˆ˜๋“  ๊ดœ์ฐฎ๋‹ค.)
  },
});

 

[Slice]

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

const initialState = [];

const monSlice = createSlice({
  name: "setMyPokemon",
  initialState,
  reducers: {
   
    addPokemon: (state, action) => {
      state.push(action.payload); 
    },
    deletePokemon: (state, action) => {
      state.pop(action.payload);
    },
  },
});

// action creater
export const { addPokemon, deletePokemon } = monSlice.actions;
// reducer
export default monSlice.reducer;

 

[Card] : ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๋ฐœ์ทŒ

const PokemonCard = ({ isAdd, data }) => {

  const dispatch = useDispatch();
  const navigate = useNavigate();

  return (
    <MonCard
      key={data.id}
      onClick={(e) => {
        {
          navigate(`/detail?id=${data.id}`);
        }
      }}
    >
      <MonImg src={data.img_url} />
      <BottomWrap>
        <MonName>{data.korean_name}</MonName>
        <p>No.{data.id}</p>
      </BottomWrap>
      {isAdd === true ? (
        <AddBtn
          className="add-card-btn"
          onClick={() => {
            dispatch(addPokemon(data));
          }}
        >
          ์ถ”๊ฐ€
        </AddBtn>
      ) : (
        <DeleteBtn
          className="remove-card-btn"
          onClick={() => {
            dispatch(deletePokemon(data));
          }}
        >
          ์‚ญ์ œ
        </DeleteBtn>
      )}
    </MonCard>
  );
};

export default PokemonCard;

 

[Dashboard] : ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๋ฐœ์ทŒ

const Dashboard = () => {
  const myMon = useSelector((a) => {   ๐Ÿ‘‰๐Ÿป์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๊ฐ€์ง, ์ฝ˜์†”์— ์ฐ์–ด๋ณด๋ฉด store๊ฐ€ ๊ฐ€์ง„ ๋ฆฌ๋“€์„œ ํ˜•ํƒœ ๊ทธ๋Œ€๋กœ ๋‚˜์˜จ๋‹ค.
    return a.setMyPokemon;   ๐Ÿ‘‰๐Ÿป ๊ทธ ์ค‘ ํ•„์š”ํ•œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ธฐ
  });
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
TAG
more
ยซ   2026/03   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
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
๊ธ€ ๋ณด๊ด€ํ•จ