redux-toolkit

2023. 2. 20. 22:19·TECH

redux의 단점! 많은 코드양

Redux 팀에서 단점을 보완하려고 만들어진 패키지 redux toolkit

Thunk, saga, immer 안써도 된다. 내장되어있다. 리덕스의 총집합

createSlice ,createAsyncThunk 두가지가 많이 사용된다. 

npm install @reduxjs/toolkit

 

createAction

액션 creator함수는 간단하게 사용할 수있도록 해준다.

// 변경전
const ADD = 'add';
const DEL = 'delete';

// action creator
const AddTodo = (text) => {
  return {
    type: ADD,
    text
  }
}
const DelTodo = (id) => {
  return {
    type: DEL,
    id
  }
}
// 변경후
import { createAction } from '@reduxjs/toolkit'

const addTodo = createAction("ADD"); //인자값으로 넣어준 값이 type이 된다.
const delTodo = createAction("DEL");

콘솔로 addTodo를 찍어보면
{type: ADD, payload: } 이렇게 찍히는 것을 볼 수있다.

기존과는 다르게 action으로 부터 파라미터로 데이터를 받는다면 payload로 받게된다. (컨벤션)

reducer에서도 액션타입을 addTodo.type으로 사용할 수있다.

// 변경전
const reducer = (state = [], action) => {
  switch(action.type) {
    case ADD: 
      return ;
    case DEL: 
      return ;
    default: 
      return;
  }
}
// 변경후
const reducer = (state = [], action) => {
  switch(action.type) {
    case addTodo.type: //createAction.type으로 써줄수있다.
      return;
    case delTodo.type: 
      return ;
    default: 
      return;
  }
}

 

createReducer()

// 기존코드
const reducer = (state = [], action) => {
  switch(action.type) {
    case AddTodo.type: 
      return ;
    case DeleteTodo.type:
      return ;
    default: 
      return ;
  }
}

switch문을 사용하지 않아도 된다.

const reducer = createReducer([], {
    [addTodo]: (state, action) => ,
  [delTodo]: (state, action) => 
})

 

중요한 점

state를 mutate해도 된다.

이전 reducer에서는 새로운객체를 반환해줬어야했다.

Redux toolkit에서는 mutate를 해도 괜찮다.

(주의할 점은 state를 수정해서 return하면 안된다. 수정은 수정만 하면 된다.)

createReducer를 사용하는경우 state변경 시 두가지 옵션

  1. 새로운 state를 리턴할수있고
  2. 기존 state를 mutate(수정) 하는 방식
    (redux toolkit은 Immer.js 아래에서 작동되기 때문에 자체로 새로운 state를 만들어 사용한다.)

 

configureStore()

이 함수는 좋은 미들웨어와 함께 store를 생성한다.

configureStore를 사용하면 redux developer tools(히스토리, 디버깅이 편리하다.) 사용할 수 있다.

const store = configureStore({
	reducer,
    // preloadedState: 서버사이드 렌더링시 state를 받을때 
});

커스텀 미들웨어가 있는 경우 middleware로 넘겨준다. 

const firstMiddleWare = (store) => (next) => (action) => {
  console.log('액션로깅', action);
  next(action);
};

const store = configureStore({
  reducer,
  middleware: [firstMiddleWare]
});

커스텀 미들웨어 넘겨주는 경우

middleware: [firstMiddleWare] 이렇게 넣어주면 toolkit이 가지고 있던 thunk 미들웨어가 제외된다.

getDefaultMiddleware를 import 해서 새로운 객체를 만들어준다. 

devTools도 환경에 맞춰 사용할 수 있다.

import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import reducer from './reducers';

const firstMiddleWare = (store) => (next) => (action) => {
  console.log('액션로깅', action);
  next(action);
};

const store = configureStore({
  reducer,
  middleware: [firstMiddleWare, ...getDefaultMiddleware()],
  devTools: false // devtool 안쓸거면 false
  devTools: process.env.NODE_ENV !== 'production',
  enhencers 
});

export default store;

 

createSlice()

createSlice는 reducer뿐만 아니라 actions도 생성해준다.

// 기존코드    
const AddTodo = createAction("ADD");
const DeleteTodo = createAction("DELETE");

const reducer = createReducer([], {
  [AddTodo]: (state, action) => {
    state.push({ text: action.payload, id: Date.now() })
  },
  [DeleteTodo]: (state, action) => {
    const filtered = state.filter((todo) => todo.id !== action.payload);
    return filtered;
  }
})

createSlice()는 reducer, actions를 export할 수있다.

const todos = createSlice({
    name: 'todoReducer',
  initialState: [],
  reducers: { // 동기적 액션들, 내부적인 액션들
    add: (state, action) => {
      state.push({text: })
    },
    remove: (state, action) =>
  },
  extraReducers: { //비동기 액션들, 외부적인 액션들
  
  }
})

// createSlice로 만든 todos.reducer로 export해서 사용
const store = configureStore({ reducer: todos.reducer });

// createSlice로 만든 todos.actions export해서 사용
const {add, remove} = todos.actions;

 

createAsyncThunk

툴킷패키지 에는 thunk가 내장되어있다.

// actions/user

const {createAsyncThunk} from '@reduxjs/toolkit';

// data(ex 아이디, 패스워드)넘기면 axios로 api호출하고 응답을 받는다.
// 코드에 user/logIn 액션이름
const login = createAsyncThunk('user/logIn', async(data, thunkAPI) => {
  // pending, fulfilled, rejected 
  const result = axios('/url');
  return result;
})
// user.reducer

createSlice({
  name: 'post',
  initialState, 
  reducers: {
    
  }, //동기적 액션들, 내부적인 액션들(user에 종속되어있는)
  extraReducers: {
    [logIn.pending](state, action) { //이름은 user/logIn/pending
    	state = null
    },
    [logIn.fulfilled](state, action) { //user/logIn/fulfilled
    	state = action.payload;
    },
    [logIn.rejected](state, action) {
    	state = null
    }
  }  // 비동기 액션들, 외부적인 액션들(user에 종속되어있지 않은), thunk로 만드는 애들
})

 

extraReducers builder를 사용해서 타입추론이 더 쉽게 수정하기

extraReducers: (builder) => builder
    .addCase(LogIn.pending, (state, action) => {})
    .addCase(LogIn.fulfilled, (state, action) => {})
    .addCase(LogIn.rejected, (state, action) => {})
    // addMatcher는 공통적인 코드 처리할 때 
    // action pending인경우는 공통적으로 isLoading = true로 변경한다.
    .addMatcher((action) => {
   	  // 조건
      return action.type.includes('/pending');
    }, (state, action) => {
      state.isLoading = true
    })
    .addDefaultCase((state, action) => {
      // default
    })

 

createSelector

import { createSelector } from '@reduxjs/toolkit' //reselect

useMemo로 최적화보다 더 나은최적화
memoiztion을 해준다고 생각하면 된다.
export해서 다른 컴포넌트에서 사용하면 안된다. 

다른컴포넌트에서 사용하고싶은경우 함수로 감싸서 다른컴포넌트에서 실행해서 그렇게 사용해야 한다.

const priceSelector = (state) => state.user.prices;

export const makeSumPriceSelector = () => createSelector{
  priceSelector,
  (prices) => prices.reduce(a, c => a + c, 0);
};

const sumPriceSelector = makeSumPriceSelector();

function App () {
  
}

 

'TECH' 카테고리의 다른 글

styled-components 기본 문법  (0) 2023.02.22
styled-components, emotion 비교  (0) 2023.02.22
redux개념 정리  (0) 2023.02.16
tsconfig.json 기본세팅, d.ts, JSDoc  (0) 2023.02.14
Typescript 기초개념 정리  (0) 2023.02.14
'TECH' 카테고리의 다른 글
  • styled-components 기본 문법
  • styled-components, emotion 비교
  • redux개념 정리
  • tsconfig.json 기본세팅, d.ts, JSDoc
ssund
ssund
  • ssund
    ssund의 기술블로그
    ssund
  • 전체
    오늘
    어제
    • 분류 전체보기 (73)
      • TECH (22)
      • NOTE (40)
      • DAILY (7)
      • javascript (1)
      • 알고리즘 (0)
  • 블로그 메뉴

    • 홈
    • TECH
    • NOTE
    • DAILY
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    JavaScript
    global-style
    theme-provider
    타입스크립트
    styled-components
    Array.sort()
    배열요소순서
    웹브라우저구성
    reat-head
    react state management
    커머스프로젝트
    TypeScript
    redux
    React
    함수와 메서드차이
    git배포
    d.ts
    slidesPerGroup
    call signatures
    reduxtoolkit
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
ssund
redux-toolkit
상단으로

티스토리툴바