ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Redux Toolkit (rtk) 사용하기
    React 2022. 11. 4. 08:53
    • 로그인 정보를 전역 상태로 사용하기 위하여 redux를 사용하기로 마음먹었다.
    • 자연스럽게 일단 전역 상태를 저장할 store를 만들기 위해 createStore를 불러왔는데, 다음과 같은 상황에 처했다.

    • 커서를 createStore에 대고 읽은 안내 메세지에 따르면, createStore는 deprecated되었고 그 대신에 @reduxjs/toolkit의 configureStore메소드를 사용하는 것을 추천받았다.

    🥔 그리고 왜 RTK를 사용해야 하는지 적혀있는 공식문서의 주소도 안내받았다.
    🥔 https://redux.js.org/introduction/why-rtk-is-redux-today

     

    Why Redux Toolkit is How To Use Redux Today | Redux

    Introduction > Why RTK is Redux Today: details on how RTK replaces the Redux core

    redux.js.org

    • 이제는 redux를 사용하는데 Redux Toolkit가 필수적인 요소가 되었고, 나 역시 Redux Toolkit을 사용하여 redux를 세팅하기로 하였다.

    configureStore

    createStore 대신에 사용하게 될 configureStore이다.

    store를 만들고, Provider로 연결해준다.

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import App from './App';
    import reducer from './redux/reducer';
    import { Provider } from 'react-redux';
    import { configureStore } from '@reduxjs/toolkit';
    
    const store = configureStore({reducer})
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <React.StrictMode>
          <Provider store={store}>
            <App/>
          </Provider>
      </React.StrictMode>
    );
    

    createSlice

    action과 reducer를 손쉽게 만들어주는 매소드이다.

    reducer만 작성하면, 자동으로 action을 만들어준다.

    import { createSlice } from "@reduxjs/toolkit";
    
    const userSlice = createSlice({
      name: "user",
      initialState: {
          nickname: "",
          error: ""
      },
      reducers: {
        setNickname: (state, action) => {
            state.nickname = action.payload;
        },
      },
      extraReducers: {},
    });
    
    export const { setNickname } = userSlice.actions; // action 생성
    export default userSlice.reducer; // reducer가 export 된다.
    • 생성된 reducer를 연결해주도록 한다.
    import { combineReducers } from 'redux';
    import user from './userSlice'; // 좀 더 직관적인 이름으로 불러와 사용한다.
    
    const reducer = combineReducers({user});
    
    export default reducer;
    
    • hook을 이용하여 전역 상태를 사용한다.
    import { useSelector, useDispatch } from "react-redux";
    import { setNickname } from '../redux/userSlice';
    
    export const component = () => {
    
        const user = useSelector(state => state.user);
        const dispatch = useDispatch();
        
    	console.log(user); // 불러온 전역 상태를 출력한다.
        
        return (<button onClick={() => dispatch(setNickname("새이름"))}>클릭!</button>);
    }
    • 버튼이 클릭되면, 전역상태 nickname이 초기 값 ""에서 "새이름"으로 변경된다.

    createAsyncThunk

    Redux Toolkit를 사용하고 있다면, 비동기 처리를 위해서 react-thunk를 설치할 필요가 없다.
    🧀 Redux Toolkit은 thunk를 내장한다.

    Redux Toolkit을 통해서 비동기 처리를 하고자 한다면, createAsyncThunk 매서드를 사용하도록 하자.

    import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
    
    export const fetchAccount = createAsyncThunk("account/getUser", async () => {
    	return fetch(url).then(el => el.json()).catch(err => err);
    });
    
    const userSlice = createSlice({
      name: "user",
      initialState: {
          nickname: "",
          account: "",
          isLodaing: false,
          error: "",
      },
      reducers: {
        setNickname: (state, action) => {
            state.nickname = action.payload;
        },
      },
      extraReducers: (builder) => {
        builder
            .addCase(fetchAccount.pending, (state, action) => {
            	state.isLodaing = true; // 로딩중
                state.account = "";
            })
            .addCase(fetchAccount.fulfilled, (state, action) => {
                state.isLodaing = false;
                state.account = action.payload;
            })
            .addCase(fetchAccount.rejected, (state, action) => {
                state.isLodaing = false;        
                state.error = action.error;
            })
      },
    });
    
    export default userSlice.reducer;
    • Promise 값을 리턴하는 비동기 함수가 필요하다. (위의 코드에서는 fetchAccount)
    • extraReducers에 builder를 사용하여, reducer를 작성한다.
    • addCase를 통해서 각 Promise의 상태마다 어떤 값을 처리할지 설정한다.
    import { useSelector, useDispatch } from "react-redux";
    import { fetchAccount } from '../redux/userSlice';
    
    export const component = () => {
    
        const user = useSelector(state => state.user);
        const dispatch = useDispatch();
        const onClickButton = async () => {
          await dispatch(fetchAccount());
          console.log("FETCH END!");
        }
    	console.log(user); // 불러온 전역 상태를 출력한다.
        
        return <S.Button onClick={onClickButton}>계정</S.Button>;
    }
    • 따로 action을 반환하지 않고, createAsyncThunk로 만든 비동기 함수가 사용된다.
    • createAsyncThunk를 사용하면, dispatch에서도 async await 문법을 사용할 수 있다.
Designed by Tistory.