React)redux-toolkit을 사용해 redux 세팅해보기

미누도 개발한다·2021년 6월 4일
0

리액트

목록 보기
2/11

사용하는 이유

이전 포스팅에서 리액트에서 리덕스를 세팅했던 방식은, 하나의 리듀서를 만들고, 하나의 리듀서에서 action값에따라 모든 state를 관리했었다.
Store의 state값이 다양해지게 되고, 컴포넌트가 많아질수록, 이를 구분할 필요가 있다.
아주 간단한 예를들면.. A컴포넌트에서는 State:{counter:number, toggle:boolean} 를 구독하고
B컴포넌트(유저인증) 에서는 state:{auth:boolean} 를 구독하고있다.
이때 A,B 컴포넌트가 독립적이므로 의미상 리듀서를 2개 놓고, dispatch를 통해 소통하는 방식이 헷갈리지않고 파일을 나누기 편리하다.

세팅

npm install @reduxjs/toolkit 을 설치한다.

store/index.js (리액트 root폴더의 index.js가 아님!)

import {createSlice,configureStore} from '@reduxjs/toolkit';

const initialCounterState = {
    counter:0,
    showCounter:true
};

const counterSlice = createSlice({
    name:'counter',
    initialState:initialCounterState,
    reducers: {
        increment(state){
            state.counter++;
        },
        decrement(state){
            state.counter--;
        },
        toggle(state){
            state.showCounter = !state.showCounter
        }
    }
});
//-----------------------------------------------------------------
  
const initialAuthState = {
    isAuthenticated:false
};

const authSlice = createSlice({
    name:'auth',
    initialState: initialAuthState,
    reducers:{
        login(state){
            state.isAuthenticated =  true;
        },
        logout(state){
            state.isAuthenticated = false;
        }
    }
});

const store = configureStore({//root reducer
    reducer: {counter: counterSlice.reducer, auth:authSlice.reducer}
});
export const counterActions = counterSlice.actions;

export const authActions = authSlice.actions;
export default store;

설명

createSlice를 사용해서, 의미상 구분된 리듀서를 만들 수 있다.


Slice객체를 만든 다음, store에 등록을 해준다.

const store = configureStore({//root reducer
    reducer: {counter: counterSlice.reducer, auth:authSlice.reducer}
});

위 부분과 같이 우리가만든 slice 리듀서를 root리듀서에 매핑을 해주어야한다.
내부적으로, 여러 리듀서들을 root리듀서에 병합 해준다

만약 구독하는 컴포넌트에서 store에 접근하려면, state.counter.counter , state.auth.isAuthenticated와 같이 매핑된 리듀서 ID를 넣어주어야한다.


export const counterActions = counterSlice.actions;
export const authActions = authSlice.actions;

컴포넌트에서 dispatch를 할때에 필요하기 때문에 위처럼 Actions객체를 export 해주어야한다.
컴포넌트에서는 Actions객체는 다음과 같이 사용한다.

import { useSelector, useDispatch } from 'react-redux';
import {authActions,counterActions} from '../store/index';

const logoutHandler = () => {
    dispatch(authActions.logout());
  }

Actions객체에 접근한 다음, slice에 정의해둔 이름과 같은 reducer를 실행시키면,
내부적으로 그에맞는 action객체를 리턴해주고 dispatch를 통해 해당 리듀서 함수를 실행시켜준다.

만약 payload가 필요하다면 dispatch(authActions.logout(payloadValue)); 를 호출하고,
store파일에서 해당 reducer에 매개변수로 (state,action)를 받으면된다. action.payload로 값을 사용하면된다.

툴킷자체가 내부적인 동작이 많기 때문에, 설명을 상세히 달아두지않으면 까먹을 것 같아서 이렇게 까지 써둔다.


특이한 점

const counterSlice = createSlice({
    name:'counter',
    initialState:initialCounterState,
    reducers: {
        increment(state){
            state.counter++;
        },
        decrement(state){
            state.counter--;
        },
        toggle(state){
            state.showCounter = !state.showCounter
        }
    }
});

이 부분이다. 상태변화를 줄때 불변성을 지키지 않고 state에 직접 접근한 다음 값 변경을 하고있다.
하지만 이는 내부적으로 state값을 clone해서(새로운 state객체 생성), 값을 변화시킨다음 override 해준다.
즉 내부적인 동작을 통해 ( immer 라이브러리를 통해 )

increment(state){
	return {
      ...state
      counter:state.counter+1;}
}

의 형태로 바꿔준다. 불변성이 지켜지고 있다.


마무리

위처럼 한 store에 모든걸 몰아넣었는데 리듀서 별로 파일로 모듈화 하는게 좋다.
분리하는것도 다음에 포스팅 해야지!

github:
https://github.com/sae1013/react-redux-demo/tree/redux-slice/src

profile
빨리 가는 유일한 방법은 제대로 가는 것이다

0개의 댓글

관련 채용 정보