Store 에서 오는 객체값이 너무나 커서, 리렌더링 될때마다 새 객체값을 생성시키고, 엄청난 양의 메모리를 소모하게 되었다.
그러므로, 평소처럼 useMemo 를 사용하여, memoizition 을 하는 방향을 모색하려는데, 나는 Redux-toolkit 을 사용한다!
Redux-toolkit 에는, 메모이제이션 을 미리 사용하여, 내보낼 수 있는 좋은 기능이 있다.
바로 createSelector 이다.
https://react-redux.js.org/api/hooks#using-memoizing-selectors
createSelector 는 기존의 useSelector 를 사용할때, 리렌더 될때마다 계속해서 새 인스턴스가 생성되는 것을 방지하고
memoization 을 사용하여 기존의 값을 재사용 할 수 있게 만들어줍니다.
또한, 기존의 useSelctor 에서 가져올때, 1차적으로 가공하여 밖으로 빼오는 함수를 사용하는 것 처럼
createSeletor 안에서, 1차적인 가공을 미리하여, 필요한 값만 빼 올 수 있도록 만들 수도 있습니다.
현재 사용하는 코드에서는, 가공은 필요 없지만
단순히 큰 객체를 가져오기에 재생성을 방지하는 목적으로 사용하였습니다.
사용방법
1. 평소처럼 slice 를 만들어줍니다.
<store / dummyAssets-slice.ts>
import { createSlice, createSelector } from "@reduxjs/toolkit";
import { RootState } from ".";
import { DummyAssets } from "../components/helper/dummyAssets";
import { DummyAttackAssets } from "../components/helper/dummyAssets";
import { DummyDefenseAssets } from "../components/helper/dummyAssets";
import { DummyCanaryAssets } from "../components/helper/dummyAssets";
export interface TypeAlgorithms {
itemId: string;
itemName: string;
}
const initialState: {
assets: TypeAlgorithms[];
attackAssets: TypeAlgorithms[];
defenseAssets: TypeAlgorithms[];
canaryAssets: TypeAlgorithms[];
} = {
assets: DummyAssets,
attackAssets: DummyAttackAssets,
defenseAssets: DummyDefenseAssets,
canaryAssets: DummyCanaryAssets,
};
const dummyAssetsSlice = createSlice({
name: "select",
initialState,
reducers: {},
});
export default dummyAssetsSlice.reducer;
2. 평소처럼 store 의 index 안에서 store의 reducer 에 등록합니다.
<store / index.ts>
import { configureStore } from "@reduxjs/toolkit";
import userStrategySlice from "./user-strategy-detail-slice";
import selectStrategySlice from "./select-strategy-algorithm-slice";
import dummyAlgorithmSlice from "./dummyAlgorithm-slice";
import dummyAssetsSlice from "./dummyAssets-slice";
export const store = configureStore({
reducer: {
strategy: selectStrategySlice,
userStrategy: userStrategySlice,
dummyAlgorithm: dummyAlgorithmSlice,
dummyAssets: dummyAssetsSlice,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
3. store 에 등록했다면, 이제 createSelector 를 만들어서, useSelector 를 사용하기 위한 사전작업에 들어갑니다.
import { createSlice, createSelector } from "@reduxjs/toolkit";
import { RootState } from ".";
import { DummyAssets } from "../components/helper/dummyAssets";
import { DummyAttackAssets } from "../components/helper/dummyAssets";
import { DummyDefenseAssets } from "../components/helper/dummyAssets";
import { DummyCanaryAssets } from "../components/helper/dummyAssets";
...
const initialState: {
...
};
const dummyAssetsSlice = createSlice({
...
});
export default dummyAssetsSlice.reducer;
// 여기부터
export const dummyAssetsSelector = (state: RootState): TypeAlgorithms[] =>
state.dummyAssets.assets; // 필요한 값을 useSelector 처럼 미리 정의합니다.
export const dummyAttackAssetsSelector = (state: RootState): TypeAlgorithms[] =>
state.dummyAssets.attackAssets; // 필요한 값을 useSelector 처럼 미리 정의합니다.
export const dummyDefenseAssetsSelector = (
state: RootState
): TypeAlgorithms[] => state.dummyAssets.defenseAssets; // 필요한 값을 useSelector 처럼 미리 정의합니다.
export const dummyCanaryAssetsSelector = (state: RootState): TypeAlgorithms[] =>
state.dummyAssets.canaryAssets; // 필요한 값을 useSelector 처럼 미리 정의합니다.
export const allAssets = createSelector( // createSelector 를 이용해, useSelctor 를 사용했을때, 어떤 값이 반환될지 정합니다.
dummyAssetsSelector,
dummyAttackAssetsSelector, // 미리 정의한 값들을 넣어주고
dummyDefenseAssetsSelector,
dummyCanaryAssetsSelector,
(assets, attackAssets, defenseAssets, canaryAssets) => ({
assets,
attackAssets, // 이곳에서, 미리 정의한 값들을 사용하면 어떤 값을 반환할지 정합니다.
defenseAssets, // (...) 가 아니라 { return ...} 을 사용해도 무방합니다.
canaryAssets, // 현재 단순 값을 넣어준 이유는, 따로 이 값들을 처리해야할 함수가 없기 때문입니다.
})
);
만약 처리후 사용하고 싶다면
(assets, attackAssets, defenseAssets, canaryAssets) => { return asset.filter(...) } 라던가
(assets, attackAssets, defenseAssets, canaryAssets) => {
if(...){
...
return ...}
}
라던가 하여 사용할 수도 있습니다.
4. 이제 컴포넌트에서 useSelector를 이용해, 사전 정의한 selector 를 사용할 수 있습니다.
< components >
import { useSelector } from "react-redux";
import { allAssets } from "../../../../store/dummyAssets-slice"; // createSelector 로 만든
const StaticStrategy = () => {
const assets = useSelector(allAssets);
console.log(assets.assets);
console.log(assets.attackAssets);
console.log(assets.defenseAssets);
console.log(assets.canaryAssets);
...
=========================================================
미리 createSelector 로 정의한 값을 넣어주면 됩니다.
반환값은 설정한 대로
export const allAssets = createSelector(
...
(assets, attackAssets, defenseAssets, canaryAssets) => ({
assets,attackAssets,defenseAssets,canaryAssets,})
);
assets,attackAssets,defenseAssets,canaryAssets 이 담긴 객체가 반환되었음을 알 수 있습니다.
'Redux, Redux-toolkit' 카테고리의 다른 글
9. State 를 빼왔다면, 따로 변수에 저장해 사용하는 것이 좋아 보인다. (0) | 2022.12.22 |
---|---|
8. [ Redux-toolkit ] 리덕스에서 fetch 사용하여 DB 의 값 GET 요청하고 STATE 에 넣기 (1) | 2022.12.20 |
7. Redux-ToolKit [ 비동기, 사이드 이펙트 있는 함수 다루기 e.g. fetch함수] with useEffect ** (0) | 2022.12.17 |
6. Redux-ToolKit [ State 다루는 몇가지 팁들 ] (0) | 2022.12.17 |
5. Redux-ToolKit [ Slice 분할하기 ] (0) | 2022.12.17 |
댓글