단계적으로 생각하자

Redux

import { configureStore, createSlice } from '@reduxjs/toolkit';
import React from 'react';
import { Provider, useDispatch, useSelector } from 'react-redux';

const counterSlice = createSlice({
  name: 'counterSlice',
  initialState: { value: 0 },
  reducers: {
    // reducer 가 아닌 reducers임
    up: (state, action) => {
      console.log(action); // { type: "counterSlice/up", payload: 2 }
      state.value = state.value + action.payload;
    },
  },
});

const store = configureStore({
  reducer: {
    counter: counterSlice.reducer,
  },
});

function Counter() {
  const dispatch = useDispatch();
  const count = useSelector((state) => {
    // console.log(state); // state = {counter: {value: 0}}
    return state.counter.value;
  });

  return (
    <div>
      {/* 리덕스 툴킷은 리듀서 함수를 참고해서 자동적으로 actionCreator를 생성해준다. */}
      <button onClick={() => dispatch(counterSlice.actions.up(2))}>+</button>
      {count}
    </div>
  );
}

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

React Redux

Redux toolkit

Redux-toolkit 설정

Redux + React Redux 구조는 간단히 이렇다.

import React from 'react';
import { Provider, useDispatch, useSelector } from 'react-redux';
import { createStore } from 'redux';

function reducer(state, action) {
  if (action.type === 'up') {
    return { ...state, value: state.value + action.step };
  }
}

const initialState = { value: 0 };

const store = createStore(reducer, initialState);

function Counter() {
  const dispatch = useDispatch();
  const count = useSelector((state) => state.value);

  return (
    <div>
      <button onClick={() => dispatch({ type: 'up', step: 2 })}>+</button>
      {count}
    </div>
  );
}

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

여기에 Redux-toolkit 을 적용하면 아래와 같다.

import { configureStore, createSlice } from '@reduxjs/toolkit';
import React from 'react';
import { Provider, useDispatch, useSelector } from 'react-redux';

// counter 라는 작은 스토어 생성
const counterSlice = createSlice({
  name: 'counterSlice',
  initialState: { value: 0 },
  reducers: {
    // reducer 가 아닌 reducers임
    up: (state, action) => {
      console.log(action); // { type: "counterSlice/up", payload: 2 }
      state.value = state.value + action.payload;
    },
  },
});

// store 안에 작은 스토어를 configure 해준다.
const store = configureStore({
  reducer: {
    counter: counterSlice.reducer,
  },
});

function Counter() {
  const dispatch = useDispatch();
  const count = useSelector((state) => {
    return state.counter.value; // state = {counter: {value: 0}}
  });

  return (
    <div>
			<button onClick={() => dispatch({ type: 'up', step: 2 })}>+</button>
      <button onClick={() => {
				// dispatch({ type: 'up', step: 2 });
	      {/* 리덕스 툴킷은 리듀서 함수를 참고해서 자동적으로 actionCreator를 생성해준다. */}
				{/* 단, actionCreator는 reducers만 자동 생성, 비동기 reducer는 직접 생성해야 한다. */}
				dispatch(counterSlice.actions.up(2)
			})}>+</button>
      {count}
    </div>
  );
}

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

위 구조가 기본 구조이며, 보통 위 구조를 아래처럼 나눠서 관리한다.