원문 : https://redux-toolkit.js.org/tutorials/basic-tutorial
주의 : 제가 이해하기 쉬운 방식으로 번역 및 첨언했습니다.
Introduction: Writing a Counter Application
Redux “Counter-Vanilla” Example
function counterReducer(state, action) {
if (typeof state == 'undefined') { return 0 }
switch (action.type) {
case 'INCREMENT': return state + 1
case 'DECREMENT': return state -1
default: return state
}
}
var store = Redux.createStore(counterReducer);
document.getElementById('incrementBtn').addEventListener('click', function(){
store.dispatch({type: 'INCREMENT'});
});
대~충 Counter를 만들어보았다.
A More Typical Counter Example
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
function increment() {
return { type: INCREMENT }
}
function decrement() {
return { type: DECREMENT }
}
function counterReducer(state = 0, action) {
console.log(action);
switch (action.type) {
case INCREMENT: return state + 1
case DECREMENT: return state - 1
default: return state
}
}
var store = Redux.createStore(counterReducer);
document.getElementById('incrementBtn').addEventListener('click', function(){
store.dispatch(increment());
});
쫌 더 실제프로젝트에서 쓸 수 있게끔 만들었다. action생성자 함수도 있고, action.type
도 상수로 두었다. 하지만, INCREMENT
라는 상수를 만드는것도, 생성자 함수를 만드는것도 모두 귀찮은 일이다. 매번 switch
안에 case
를 써주는 일도!
Introducing: configureStore
configureStore는 내부적으로 createStore를 쓴다. 하지만, configureStore는 안에서 Redux DevTools Extension과 몇가지 유용한 middleware를 자동으로 설정해주는 이점이 있다.
// Before:
const store = createStore(counterReducer)
// After:
const store = configureStore({
reducer: counter
Reducer
})
위의 코드에서 보이듯이, 인자값으로 객체를 넣어줘야한다.
Introducing: createAction
// 원래 방식
const INCREMENT = 'INCREMENT'
function incrementOriginal() {
return { type: INCREMENT }
}
console.log(incrementOriginal())
// {type: "INCREMENT"}
// 더 편한 방식 : action creator를 만들어주는 createAction함수 사용.
const incrementNew = createAction('INCREMENT')
console.log(incrementNew())
// {type: "INCREMENT"}
엄밀히 말하면 createAction
이 action object
를 만들어 주는게 아니라 action을 생성하는 함수를 만들어 주는거니까 createActionCreator
가 더 맞겠지만 좀 간장공장공장장 같아서 createAction
으로 명명되었다.
물론! .toString()
함수나 .type
property를 사용해서 action type
을 문자열로 얻을 수 있다.
const increment = createAction('INCREMENT')
console.log(increment.toString())
// "INCREMENT"
console.log(increment.type)
// "INCREMENT"
createAction함수를 써서 다시 Counter App을 작성해보자.
const increment = createAction('INCREMENT')
const decrement = createAction('DECREMENT')
function counterReducer(state = 0, action) {
switch (action.type) {
case increment.type:
return state + 1
case decrement.type:
return state - 1
default:
return state
}
}
const store = configureStore({
reducer: counterReducer
});
var store = Redux.createStore(counterReducer);
document.getElementById('incrementBtn').addEventListener('click', function(){
store.dispatch(increment());
});
Good~
Introducing: createReducer
const increment = createAction('INCREMENT')
const decrement = createAction('DECREMENT')
const counter = createReducer(0, {
[increment.type]: state => state + 1,
[decrement.type]: state => state - 1
})
코드가 많이 짧아졌고, 어떤 점에서 switch문을 대체했는지도 알아보기 쉽다. 그리고, createReducer안에서 .toString()
을 호출해주기 때문에 아래와 같이 작성해도 된다.
const counter = createReducer(0, {
[increment]: state => state + 1,
[decrement]: state => state - 1
})
Introducing: createSlice
지금까지 작성한 코드를 살펴보자.
const increment = createAction('INCREMENT')
const decrement = createAction('DECREMENT')
const counter = createReducer(0, {
[increment]: state => state + 1,
[decrement]: state => state - 1
})
const store = configureStore({
reducer: counter
})
document.getElementById('increment').addEventListener('click', () => {
store.dispatch(increment())
})
나쁘지 않다. 코드가 많이 짧아졌다. 하지만, 한걸음 더 나아가서 aciton과 reducer를 합칠 수 있다. 둘은 counter에서 쓰인다는 공통점이 있기때문에 코드를 읽을 때도 (문맥상?) 더 편할것이다.
const counterSlice = createSlice({
name: 'counter',
initialState: 0,
reducers: {
increment: state => state + 1,
decrement: state => state - 1
}
})
;
const store = configureStore({
reducer: counterSlice.reducer
})
;
document.getElementById('incrementBtn').addEventListener('click', () => {
store.dispatch(counterSlice.actions.increment())
});
만약에 counterSlice.actions.increment()라고 길게 쓰는게 불편하면 ES6의 destructuring syntax 문법을 사용하면 된다.
const { actions, reducer } = counterSlice
const { increment, decrement } = actions
요약
configureStore
: store를 생성하는 함수인데, 안에서 Redux DevTools Extension과 몇가지 유용한 middleware를 설정해 놓았다.createAction
: action을 만들어주는 함수를 만들어주는 함수이다.createReducer
: switch문을 안써도 reducer를 만들어준다.createSlice
: 이게 진국. action과 reducer를 묶어준다. 이 묶음을 slice라고 부르는듯.
다음글 : https://develoger.kr:80/redux-toolkit-intermediate-tutorial/