til
til copied to clipboard
Redux
Redux
무슨
Re-
가 이렇게 많냐...
React
: 각각의 Component 혹은, 공통된 부모가 state를 관리합니다.
Redux
: Store를 하나 만들어서 state를 관리합니다.
Concepts
Action ---> Reducer ---> Store(state)
Store
Store는 state를 관리합니다. 특정 Action이 발생할 경우, Reducer로 이를 처리합니다. 이를 위해 Store를 생성할 때, Reducer를 전달해야 합니다. Reducer를 여러개 사용하기 위해서는 Redux가 제공하는 combineReducers
를 사용합니다.
Store는 Redux를 사용하는 어플리케이션에서 하나만 사용할 수 있습니다.
Action
Action은 { type: "SOME_TYPE", someKey: "SOME_VALUE" }
형태의 JSON 객체를 의미합니다. 이런 객체를 생성하는 함수를 여러개 정의해서 사용합니다.
Dispatch
Store에 정의된 dispatch
함수는 특정 Action을 Store로 전달 합니다.
Reducer
Reducer는 현재 Store의 state
와 전달 받은 action
을 조합해서 새로운 state
를 만들어 냅니다.
Store 생성
기본 생성
import { createStore } from 'redux'
import rootReducer from './reducer'
const store = createStore(rootReducer)
export default store
초기 상태 지정
import { createStore } from 'redux'
import rootReducer from './reducer'
let preloadedState
const persistedTodosString = localStorage.getItem('todos')
if (persistedTodosString) {
preloadedState = {
todos: JSON.parse(persistedTodosString)
}
}
const store = createStore(rootReducer, preloadedState)
Enhancer 지정
Enhancer : Store를 감싸서 새로운 기능을 제공합니다.
dispath
,getState
,subscribe
메소드를 재정의 할 수 있습니다.
import { createStore, compose } from 'redux'
import rootReducer from './reducer'
import {
sayHiOnDispatch,
includeMeaningOfLife
} from './exampleAddons/enhancers'
const composedEnhancer = compose(sayHiOnDispatch, includeMeaningOfLife)
const store = createStore(rootReducer, undefined, composedEnhancer)
export default store
react-redux
react-redux
는 Provider
, useSelector
, useDispatch
등의 기능을 제공해준다.
Middleware
Redux middleware provides a third-party extension point between dispatching an action, and the moment it reaches the reducer.
Middleware는 dispatch
동작을 맞춤화(customize) 하기 위해 사용합니다. Action이 Reducer에 전달되기 전에 사전에 지정된 작업을 수행합니다.
Action ---> Middleware ---> Reducer ---> Store(state)
Redux의 Middleware는 Store Enhancer의 구현체입니다. 따라서 다음과 같이 스토어를 생성할 때 middleware를 Enhancer로 전달할 수 있습니다.
import { createStore, applyMiddleware } from 'redux'
import rootReducer from './reducer'
import { print1, print2, print3 } from './exampleAddons/middleware'
const middlewareEnhancer = applyMiddleware(print1, print2, print3)
// Pass enhancer as the second arg, since there's no preloadedState
const store = createStore(rootReducer, middlewareEnhancer)
export default store
Middleware는 다음과 같이 정의할 수 있습니다.
const loggerMiddleware = storeAPI => next => action => {
console.log('dispatching', action)
let result = next(action)
console.log('next state', storeAPI.getState())
return result
}
-
storeAPI
:{dispatch, getState}
함수를 갖는 객체입니다. -
next
: 미들웨어 파이프라인에 있는 다음 미들웨어를 의미합니다. 현재 미들웨어가 마지막 미들웨어라면, 실제store.dispatch
함수를 의미합니다. -
action
: 전달 받은 action 객체를 의미합니다.
Redux Persist
Redux의 Store는 앱을 종료하면 사라집니다. Store를 저장하기 위해 Redux Persist를 사용합니다.
persistReducer
, persistStore
를 사용합니다 다음과 같이 사용합니다.
// configureStore.js
import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web
import rootReducer from './reducers'
const persistConfig = {
key: 'root',
storage,
}
// rootReducer를 감싸는 persistReducer 생성
const persistedReducer = persistReducer(persistConfig, rootReducer)
export default () => {
let store = createStore(persistedReducer)
// store를 감싸는 persistor 생성
let persistor = persistStore(store)
return { store, persistor }
}
이렇게 생성된 store
와 persistor
를 각각 react-redux
의 Provider
와 redux-persist
의 PersistGate
에 전달합니다.
import { PersistGate } from 'redux-persist/integration/react'
// ... normal setup, create store and persistor, import components etc.
const App = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootComponent />
</PersistGate>
</Provider>
);
};
Redux i18n
다국어를 지원하기 위한 모듈입니다. 현재 언어 설정을 저장하기 위해 redux store를 사용합니다.
공식 문서 참고
Redux Saga
특정 Action이 발생했을 때 원하는 동작을 실행시켜주는 미들웨어 입니다. Generator문법을 사용합니다.