Open herrero-tranquilo opened 4 years ago
- 사용중인 typesafe-actions와 비교를 좀 해보자
"immer": "^6.0.1",
/*리듀서작성시 불변성을 유지하며 코드를 작성하는데 편리함*/
"redux": "^4.0.0",
"redux-thunk": "^2.3.0",
/*사가를 사용중이라 의미는 없음*/
"reselect": "^4.0.0"
/*스토어의 데이터를 줄이고 가공을 분리하는데 편리함 memoization을 지원*/
Immer
Reselect
미들웨어로는 thunk를 default로 하고있어 saga를 사용하는데 문제가 있는 것은 아니지만 몇몇 api들이 thunk와 잘 맞는듯 보인다.
configureStore
createStore combineReducers compose applyMiddleware devtools enhancer
를 편하게 사용 할 수 있는 configureStore를 지원한다.createSlice
스토어를 캡슐화. 보일러플레이트 코드를 줄여 적은 코드량으로 덕타이핑 할 수있도록 createSlice api를 제공한다.
extraReducers 프로퍼티를 사용해 해당 슬라이트 외 다른 리듀서의 액션에 반응해야 할 경우 조금 더 깔끔한 코드작성이 가능 할 것 같다.
import { createSlice, createAction, PayloadAction } from '@reduxjs/toolkit'
import { createStore, combineReducers } from 'redux'
const incrementBy = createAction<number>('incrementBy')
const decrementBy = createAction<number>('decrementBy')
const counter = createSlice({
name: 'counter',
initialState: 0 as number,
reducers: {
increment: state => state + 1,
decrement: state => state - 1,
multiply: {
reducer: (state, action: PayloadAction<number>) => state * action.payload,
prepare: (value: number) => ({ payload: value || 2 }) // fallback if the payload is a falsy value
}
},
// "builder callback API", recommended for TypeScript users
extraReducers: builder => {
builder.addCase(incrementBy, (state, action) => {
return state + action.payload
})
builder.addCase(decrementBy, (state, action) => {
return state - action.payload
})
}
})
/*아래와 같은 사용이 가능*/
export const { increment, decrement, multiply } = counter.actions
store.dispatch(counter.actions.increment())
// -> { counter: 1, user: {name : '', age: 21} }
===========================================
const user = createSlice({
name: 'user',
initialState: { name: '', age: 20 },
reducers: {
setUserName: (state, action) => {
state.name = action.payload // mutate the state all you want with immer
}
},
// "map object API"
extraReducers: {
[counter.actions.increment]: (state, action) => {
state.age += 1
}
}
})
==============================================
const reducer = combineReducers({
counter: counter.reducer,
user: user.reducer
})
const store = createStore(reducer)
https://github.com/reduxjs/redux-toolkit
https://github.com/piotrwitek/typesafe-actions
redux-observable과 redux-saga를 사용하는 api 사용 예시를 들고있다. async-flows
import { ActionType } from 'typesafe-actions';
// with "import as ..."
import as todos from './actions';
export type TodosAction = ActionType
// with nested action-creator map case
const actions = {
action1: createAction('action1'),
nested: {
action2: createAction('action2'),
moreNested: {
action3: createAction('action3'),
},
},
};
export type RootAction = ActionType
헬퍼 타입을 만들어도 될 듯 하고 아니어도 아직 딱히 불편함을 느끼진 못한부분
```javascript
import { combineReducers } from 'redux';
import { StateType } from 'typesafe-actions';
// with reducer function
const todosReducer = (state: Todo[] = [], action: TodosAction) => {
switch (action.type) {
case getType(todos.add):
return [...state, action.payload];
...
export type TodosState = StateType<typeof todosReducer>;
// with nested/combined reducers
const rootReducer = combineReducers({
router: routerReducer,
counters: countersReducer,
});
export type RootState = StateType<typeof rootReducer>;
이부분도 아직 불편한지 모르겠다.
usermenu 클릭으로 변경 commit 628e52dcf12ecc8c04760285331a64311503db83
계속해서 변경 :sunglasses:
공통, 재사용될 스타일은 상위 테마로 꺼내기
redux 데이터 관련 코드
비동기관련 코드
TODO