Redux

2024-11-11
Redux, Redux Toolkit 정리


Redux 소개

Javascript의 상태 관리 라이브러리로, 주로 React와 함께 사용된다.
Store이라는 저장소에 모든 정보를 저장해서 프론트엔드의 DB처럼 작동한다.

One way data flow
Redux

  1. App에서 Store의 State 데이터를 사용한다.
  2. App에서 Dispatch로 등록된 Action을 실행해 Store의 데이터를 변경한다.
  3. Store의 데이터는 수정 불가능(immutable) 상태로 Reducer를 이용해 새로운 객체를 만들어 덮어씌운다.


  • Store : 모든 Slice 데이터를 저장하는 저장소
  • Provider : React에서 Store를 연결하기 위한 컴포넌트


  • Slice : Store에 저장할 데이터 형식
  • State : 현재 Store에 저장된 Slice 데이터
  • initialState : Slice가 처음 정의될 때 설정하는 초기 상태 값


  • Reducer : 새로운 State를 기존 State에 덮어씌우는 함수
  • Action : 데이터를 변경시키기 위한 명령으로 type, payload 속성을 가진 객체이다.
    • type : 어떤 동작을 수행할지 - Reducer 선택
    • payload : 그 동작에 필요한 데이터

Redux 사용

  1. Redux를 설치한다.
  2. Store를 만들고 최상위 컴포넌트에 Provider로 설정한다.
  3. Slice, Reducer, Action를 생성한다.
  4. 컴포넌트에서 State와 Action을 사용한다. (useSelector, useDispatch)

1. Redux 설치

npm install @reduxjs/toolkit react-redux

2. Store, Provider

데이터를 저장할 Store를 생성한다.

// Store (store.ts)

import { configureStore } from '@reduxjs/toolkit';
// 데이터를 명시한 Slice의 Reducer
import statusDataReducer from './statusDataSlice';

// Store를 생성하고 Reducer 등록
const store = configureStore({
  reducer: {
    statusData: statusDataReducer,
  },
});

// Store, Type 내보내기
export type RootState = ReturnType<typeof store.getState>;
export type AppDispath = typeof store.dispatch;
export default store;

Store를 사용할 최상위 컴포넌트에 Provider를 설정한다.

// Provider (Layout.tsx)

import { Provider } from 'react-redux';

export default function Layout() {
  return (
    <Provider store={store}>
      <App />
    </Provider>
  );
}

3. Slice, Reducer, Action

Slice를 생성하고 Reducer를 등록한다.
Reducer와 Action을 내보낸다.

// Slice, Reducer, Action (statusSlice.ts)

const initialState: StatusData = {};

// reducer
const addStatus = (
  state: WritableDraft<StatusData>,
  action: PayloadAction<{ key: string; time: number }>
) => {
  // payload에서 입력값을 받아 사용
  const { key, time } = action.payload;

  if (state[key]) {
    const data = state[key];

    // 평균 값 추가 (mean * count + ne wValue) / (count + 1);
    data.mean = (data.mean * data.count + time) / (data.count + 1);
    data.count += 1;
  } else {
    state[key] = { mean: time, count: 1 };
  }
};

// slice
export const statusSlice = createSlice({
  // slice name은 action.type에 명시하기 위해 사용한다.
  name: 'statusData',
  initialState,
  reducers: {
    addStatusData,
  },
});

// actions
export const { addStatus: addStatusAction } = statusSlice.actions;
// slice 내보내기
export default statusSlice.reducer;

4. State, Action, Dispatch

State 데이터를 사용하고 Action을 사용해 데이터를 변경한다.

// State, Action, Dispatch (Status.tsx)

import { useDispatch, useSelector } from 'react-redux';
import { addStatusAction } from '@/stores/statusSlice';

export default function Status(){}
	// store에 저장된 state 데이터를 사용
	const statusData = useSelector((state: RootState) => state.statusData);

	// action을 전송하기 위한 dispatch
	const dispatch = useDispatch();
	// action을 사용할 함수 정의
	const addStatus = ()=>{
		// dispatch를 이용해 action 명령을 전송
		dispatch(addStatusAction({...}));
	}
	...
	return <div onClick={addStatus}/>
}