특징
SSR이 가능하다.
- next-redux-wrapper를 사용하면 SSR에서도 store에 접근이 가능하다.
Entity(RTK - slice)간에 조합이 자유롭다.
가장 크게 아래 두 기능이 강력하다.
- A Entity의 Action에 따라 B Entity의 상태를 변경할 수 있다.
- A Entity Getter, B Entity Getter를 조합해서 (캐싱된) 값을 가져올 수 있다.
API
createEntityAdapter
정규화된 Entitry 상태를 관리하기 위해 빈번히 사용하는 CRUD 패턴의 Reducer 함수를 제공하는 API
Client에서 정규화된 데이터 관리가 필요할까?
https://redux.js.org/usage/structuring-reducers/normalizing-state-shape
https://redux.js.org/usage/structuring-reducers/updating-normalized-data
export interface EntityAdapter<T> extends EntityStateAdapter<T> {
// entity의 id를 지정하는 함수
// selectId를 설정하지 않다면, 기본값으로 entity => entity.id가 설정된다.
// 만약 id외에 다른 값을 id로 설정하고 싶다면 selectId를 설정해야 한다.
selectId: IdSelector<T>
// 1개이상의 entitry가 있을 때 정렬기준을 설정한다.
// CRUD 함수에 의해 변경됐을 때만 정렬을 다시한다.
sortComparer: false | Comparer<T>
// 초기 state를 다음과 같은 형태로 반환한다.{ids: [], entities: {}}
// 매개변수로 초기화할 추가 state를 설정할 수 있다.
getInitialState(): EntityState<T>
getInitialState<S extends object>(state: S): EntityState<T> & S
// 엔티티를 조회할 수 있는 함수 모음을 제공한다.
// selectIds, selectEntities, selectAll, selectTotal, selectById
getSelectors(): EntitySelectors<T, EntityState<T>>
getSelectors<V>(
selectState: (state: V) => EntityState<T>
): EntitySelectors<T, V>
}
import {
createEntityAdapter,
createSlice,
configureStore,
} from '@reduxjs/toolkit'
type Book = { bookId: string; title: string }
const booksAdapter = createEntityAdapter<Book>({
// Assume IDs are stored in a field other than `book.id`
selectId: (book) => book.bookId,
// Keep the "all IDs" array sorted based on book titles
sortComparer: (a, b) => a.title.localeCompare(b.title),
})
const booksSlice = createSlice({
name: 'books',
initialState: booksAdapter.getInitialState(),
reducers: {
// Can pass adapter functions directly as case reducers. Because we're passing this
// as a value, `createSlice` will auto-generate the `bookAdded` action type / creator
bookAdded: booksAdapter.addOne,
booksReceived(state, action) {
// Or, call them as "mutating" helpers in a case reducer
booksAdapter.setAll(state, action.payload.books)
},
},
})
const store = configureStore({
reducer: {
books: booksSlice.reducer,
},
})
type RootState = ReturnType<typeof store.getState>
console.log(store.getState().books)
// { ids: [], entities: {} }
// Can create a set of memoized selectors based on the location of this entity state
const booksSelectors = booksAdapter.getSelectors<RootState>(
(state) => state.books
)
// And then use the selectors to retrieve values
const allBooks = booksSelectors.selectAll(store.getState())
반응형
'FrontEnd > Redux' 카테고리의 다른 글
[Redux] redux-thunk (0) | 2023.08.14 |
---|---|
[ReduxToolkit] createAsyncThunk (0) | 2023.08.14 |
[Redux] redux-orm (0) | 2023.08.10 |