https://light9639.github.io/Redux-Toolkit-Axios-AsyncThunk/
✨ Redux-Toolkit의 AsyncThunk 기능을 Axios로 구현한 연습 페이지입니다. ✨
- React 생성
npm create-react-app my-app
# or
yarn create react-app my-app
- vite를 이용하여 프로젝트를 생성하려면
npm create vite@latest
# or
yarn create vite
- 터미널에서 실행 후 프로젝트 이름 만든 후 React 선택, Typescirpt 선택하면 생성 완료.
- Redux-Toolkit 설치 명령어
npm install redux react-redux @reduxjs/toolkit
# or
yarn add redux react-redux @reduxjs/toolkit
- axios 설치 명령어
npm install axios
# or
yarn add axios
react-redux
에서Provider
함수 가져온 후store.ts
파일을import
한 후<Provider store={store}></Provider>
으로<App />
을 둘러싸면Redux-Toolkit
사용준비 완료.
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import { Provider } from 'react-redux'
import { store } from './redux/store'
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
)
redux
함수를 사용하고 싶으면useSelector
,useDispatch
를import
한 뒤에 사용하면 된다.- 그러나 위의 2가지 함수들은
type
적용이 안 되어 있기 때문에useTypedSelector.ts
의useAppDispatch
,useAppSelector
를 가져와서 사용하는 것이 더 좋다.
import { useSelector, useDispatch } from "react-redux";
import { fetchUser } from "./redux/userSlice";
import React, { useEffect } from "react";
import { RootState } from "./redux/store";
import { Dispatch } from "redux";
import { useAppDispatch, useAppSelector } from "./hooks/useTypedSelector";
export default function App(): JSX.Element {
const dispatch = useAppDispatch();
// RootState가 useSelector에서 state의 타입으로 사용된 것
const { users, loading, error } = useAppSelector(state => state.users);
return (
<div className="App" style={{ margin: "0 auto", textAlign: "center" }}>
<h1>Redux-tookit with Thunk</h1>
<button onClick={() => dispatch(fetchUser())} style={{ display: "inline-block", padding: "10px 15px", borderRadius: "5px" }}>정보 가져오기</button>
{users?.length > 0 &&
users.map((user) =>
<div key={user.index} style={{ textAlign: "center", margin: "0 auto" }}>
<img src={user.src} alt={user.alt} style={{ display: "block", maxWidth: "300px", margin: "25px auto", borderRadius: "15px" }} />
{user.name}
</div>
)}
</div>
)
}
Redux-toolkit
의 내장 기능인createAsyncThunk
를 생성 후extraReducers
작성하게 되면axios
를 통한 자료 전송이 가능해진다.
import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit";
import axios from "axios";
import { store } from "./store";
import { CommonType } from "../Type/TypeBox";
interface initialType {
users: CommonType[],
loading: boolean,
error: string | undefined
}
const initialState: initialType = {
users: [],
loading: false,
error: ""
}
export const fetchUser = createAsyncThunk(
'counterSlice/asyncUpFetch',
async () => {
return axios({
method: "get",
url: "https://raw.githubusercontent.com/light9639/Shoe-Store/main/data/Shoes.json"
}).then(response => response.data.Kids);
}
)
// slice 생성
const usersSlice = createSlice({
// slice 이름 정의
name: "users",
// 초기 값
initialState,
// 리듀서
reducers: {},
extraReducers: (builder) => {
builder.addCase(fetchUser.pending, (state) => {
state.loading = true;
}),
builder.addCase(fetchUser.fulfilled, (state, action) => {
state.users = action.payload;
state.loading = false;
}),
builder.addCase(fetchUser.rejected, (state, action: PayloadAction<any>) => {
state.loading = false;
})
}
});
// useSelector 사용시 타입으로 사용하기 위함
export type RootState = ReturnType<typeof store.getState>
// useDispatch를 좀 더 명확하게 사용하기 위함
export type AppDispatch = typeof store.dispatch
// slice를 내보냄
export default usersSlice.reducer;
configureStore
안에userSlice
의reducer
를 가져온 후export
함으로써 함수를 사용 가능하게 함.
import { configureStore } from "@reduxjs/toolkit";
import { useDispatch } from 'react-redux';
import userReducer from "./userSlice";
export const store = configureStore({
reducer: {
users: userReducer
}
});
useDispatch
,useSelector
의 타입은 번번히 지정하기보다useAppDispatch
,useAppSelector
를 저장하고import
함으로써type
지정의 수고를 덜 수 있다.
import { useDispatch, useSelector } from "react-redux";
import type { TypedUseSelectorHook } from "react-redux";
import type { RootState, AppDispatch } from "../redux/store";
export const useAppDispatch: () => AppDispatch = useDispatch;
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
axios
로 가져올 데이터의 타입 지정.
export type CommonType = {
index: number;
src: string;
alt: string;
name: string;
info: string;
price: string;
Gender: string;
href: string;
star: {
first: string;
second: string;
third: string;
four: string;
five: string;
};
Review: number;
count: number;
}
- 출처 1 : Redux-Toolkit 홈페이지
- 출처 2 : Velog 글