reducer
는 상태관리를 보다 원할하게 하기위한 라이브러리입니다. 하지만 이 리덕스를 처음 마주치게 된다면 엄청 복잡하게 느껴질 것입니다. 액션 객체를 만들고, 액션 생성함수를 만들고 리듀서 함수를 만들고.. 일일히 해야될께 많습니다.
이러한 과정을 어느정도 보완해주기 위해서 툴킷이 등장합니다.
configureStore()
configureStore는 createStore를 추상화한 것입니다.
이전의 코드가 이랬다면
이렇게 줄일 수 있습니다.
라우터와 비슷하게, store와 들어온 action을 연결해주는 역할을 합니다.
리액트 앱에서는 이 store를 임포트해서 Provider로 제공해줍니다.
createReducer()
상태에 변화를 일으키는 리듀서 함수를 생성하는 util 함수입니다.
기존의 리덕스는 switch-case문을 사용해서 action type마다 case를 통해 관리했습니다. 이는 다양한 사이트 이펙트를 발생시켰습니다.
redux-toolkit가 액션을 처리하는 방법은 build callback
과 map object
두 가지 표기업이 있습니다.
Typscript와 호환성을 위해 이 표기법이 더 선호됩니다.
const counterReducer = createReducer(initialState, (builder) => {
builder
.addCase(increment, (state) => {})
.addCase(decrement, (state) => {})
})
.addCase(actionCreator, reducer);
특정 action type과 맵핑되는 case reducer를 추가합니다.
밑에 나오는 메서드보다 먼저 작성되야합니다.
.addMatcher(matcher, reducer);
새로 들어오는 모든 액션에 대해서 사용자가 작성한 matcher함수와 일치하는지 확인하고 리듀서를 실행합니다.
.addDefaultCase;
어떤 case reduce나 matcher 리듀서도 실행되지않았다면 기본 케이스 리듀서가 실행됩니다.
액션 타입 문자열을 key로 사용하는 객체를 받고, values는 해당 액션 타입을 처리하는 case reducer입니다.
builder callback 표기법 보다 짧게 작성할 수 있지만 Jascript를 사용할 떄 유효합니다.
const counterReducer = createReducer(0, {
increment: (state, action) => state + action.payload,
decrement: (state, action) => state - action.payload
})
const counterReducer = createReducer(0, {
increment: (state, action) => state + action.payload,
decrement: (state, action) => state - action.payload
})
const increment = createAction('increment')
const decrement = createAction('decrement')
const counterReducer = createReducer(0, {
[increment]: (state, action) => state + action.payload,
[decrement.type]: (state, action) => state - action.payload
})
createAction()
기존 리덕스 액션을 정의하는 방법은 액션 타입 상수와 액션 생성자 함수를 분리하여 선언하였습니다.
createAction
함수를 통해 이를 하나로 결합하여 추상화합니다.
const INCREMENT = 'counter/increment'
function increment(amount: number) {
return {
type: INCREMENT,
payload: amount,
}
}
const action = increment(3) // { type: 'counter/increment', payload: 3 }
```![](https://velog.velcdn.com/images/tastestar/post/cde1af46-c271-4209-a38c-d6720d8a66cc/image.png)
- RTK
```javascript
import { createAction } from '@reduxjs/toolkit'
const increment = createAction('counter/increment')
const action = increment(3) // { type: 'counter/increment', payload: 3 }
createSlice()
createSlice 메서드를 사용하면 앞선 createAction과 createReducer를 따로 작성할 필요가 없습니다.
createSlice메서든 a.initialState, b.reducer 함수들의 객체 c.slice이름 d.extraReducers을 받아서 이에 상응하는 action creator와 action type을 자동으로 생성합니다
const counterSlice = createSlice({
name: 'counter',
initialState: 0,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(incrementBy, (state, action) => {
/* -- */
})
}
})
extraReducer를 통해 비동기를 처리하고
reducers에 reducers에 함수를 dispatch로 함수를 호출하여 상태를 변경할 수 있습니다.
createAsyncThunk()
createAction 비동기를 위해서 제안되었습니다.
액션 타입 문자열과, 프로미스를 반환하는 콜백함수를 인자로 받아서 해당 액션타입을 접두어로 사용하는 프로미스 생명 주기 기반의 액션타입을 생성합니다.
createSelector()
리덕스 스토어 상태에서 데이터를 추출할 수 있도록 도와주는 유틸리티입니다.
한번 기록하고나니, 간단히 쓸 수 있는 tool-kit이었는데 프로젝트 중간에는 왜그렇게 큰 부담으로 느껴졌을까요. 다음에는 잘 써보도록하고 문제가 생기면 추가하도록 하겠습니다.
주의할점은 redux를 사용한 상태관리는 오로지 redux로만 가능합니다. 임의로 store에 접근할 수 없습니다.
그리고 다음에 사용할 때는 image를 리덕스로 관리하면 좋을꺼같다.
http://blog.hwahae.co.kr/all/tech/tech-tech/6946/
https://mjn5027.tistory.com/36
https://medium.com/@jsh901220/react%EC%97%90-redux-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-2-63f3e5a22003