TIL-220607

tk_jang·2022년 6월 7일
0

TIL

목록 보기
8/11

리덕스 툴킷 기본 설계

먼저 reduxtk 폴더를 생성후 먼저 wordSlice.tsx 파일을 만들어준다.

import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit'
import wordApi from '../api/wordApi'


export interface IWords{
    id: number,
    word: string,
    description: string,
    example: string,
}

// Define a type for the slice state
export type Word =  {
    word: Array<IWords>,
    
}

// Define the initial state using that type
const initialState: Word = {
    word: []
}

export const fetchUserById = createAsyncThunk(
    'word/GET',
    async (path: string) => {
        return wordApi
            .get(path)
            .then((res) => res.data)
            .catch((error) => error)
        
    }
)


export const wordSlice = createSlice({
    name: 'word',
    // `createSlice` will infer the state type from the `initialState` argument
    initialState,
    reducers: {
        ADD: (state, action: PayloadAction<IWords>) => {
            console.log(action.payload)
            state.word.push(action.payload)
        },
        UPDATE: (state, action: PayloadAction<IWords>) => {
            if (action.payload.id !== undefined && action.payload.id !== null) {
                
                state.word.map((v) => {
                    if (action.payload.id === v.id) {
                        return state.word[v.id] = { ...action.payload }
                    } else {
                        return v
                    }
                })
                
            }
        },
        DEL: (state, action: PayloadAction<number>) => {
            state.word = state.word.filter(v => {
                return v.id !== action.payload
            })
        }
    },
    extraReducers: (builder) => {
    // Add reducers for additional action types here, and handle loading state as needed
        builder
            .addCase(fetchUserById.fulfilled, (state, action) => {
                // Add user to the state array
                state.word.push(...action.payload)
            })
  },

});


export const { ADD, DEL ,UPDATE} = wordSlice.actions


export default wordSlice.reducer

다음으로 store.tsx 를 만들어준다.

import { configureStore  } from '@reduxjs/toolkit'
import wordSlice from './wordSlice'
import wordApi from '../api/wordApi'
// ...

export const store = configureStore({
    reducer: wordSlice,
    middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
        thunk: {
            extraArgument: wordApi,
        },
        serializableCheck: false,
    }),
})

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

다음 사용할 커스텀 훅을 만들어 준다.

import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'

// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () => useDispatch<AppDispatch>()
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

굳이 이렇게 커스텀 훅을 만들어주는 이유는
사용할떄마다 타입을 지정해주기 귀찮기 떄문이다.

리덕스 툴킷 작동 방식(개인적인 생각)

아직 자세히 알아보지않았지만 사용하면서 작동 방식에대해 생각해봤다 .

먼저 나는 처음에 api 의 데이터를 가져오기 위해서
wordSlice 안에 있는 fetchUserById 라는 createAsyncThunk 로 만든 함수를 디스패치 시켰다 .

해당 함수를 디스패치 시키면

해당 함수가 실행되고 상태값을 반황한다 이때 가지는 상태 값은

pending , fulfilled, rejected
이렇게 3가지가 있다
느낌상 왼쪽부터 준비 완료 실패 인것 같다.

해당 값을 리턴 받으면 wordSlice 안에 extraReducers 의 케이스를 검사해서 해당 케이스를 실행 시킨다.

또 reducers 에 추가한 액션들은

내가 따로 지정 해주지 않아도 그냥 이름을 적는대로 추가가 된다.

실행방법은

	const wordLists = useAppSelector((state) => state.word)
 	const addWords = useCallback(
        (word: IWords) => dispatch(ADD(word)),
        [dispatch]
    );    
    addWords(inputData);

위같은 방법으로 실행방법은 그냥 리덕스와 똑같다.

0개의 댓글