Redux Toolkit

혜빈·2024년 8월 6일

보충내용

목록 보기
11/38

Redux

  • 상태관리자
  • 프로그램이 동작하는데 필요한 데이터를 체계적으로 관리해줌
  • Redux 자체는 React와 무관함
  • JS 프로젝트라면 어디에서나 사용 가능
  • createStore
  • subscribe
  • getState
  • dispatch

React Redux

  • 리액트에서 리덕스를 사용하기 편리하게 해줌
  • connect
  • useDispatch
  • useSelector

Redux toolkit

  • configureStore
  • createSlice
  • createAsyncThunk

Redux toolkit 등장 배경

  • 많은 설정
  • 번거로운 미들웨어 설치
  • 반복되는 코드
  • 불변성 유지의 어려움

실전 코드 예시

  • 버튼 클릭시 증가하는 카운트 만들기

App.js

import React from 'react';
function Counter() {
	return(
    	<div>
        	<button>+</button> 0
        </div>
        )
}

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

기존 방식으로 store 생성

  1. createStore 호출
import { createStore } from 'redux';
  1. reducer 정의, 초기값 제공(value:0)
function reducer(state, action) {
	return state;
}
const initialState = {value:0}
  1. 만든 store를 provider를 통해 애플리케이션에 공급해주기
import {Provider, useSelecor} from 'react-redux';

const store = createStore(reducer, initialState);

<Provider store={store}>
</Provider>
  1. counter가 store에 value 값을 가져옴(useSelector 사용)
import { useSelector } from 'react-redux';

	const count = useSelector(state=>state.value);

	<button>+</button> {count}
  1. 버튼 클릭시 state 값을 바꾸는 dispatch 작업하기, dispatch의 action값 넣어주기
import { useDispatch } from 'react-redux';

	const dispatch = useDispatch();

	<button onClick={()=>{
    	dispatch({type:'up', step:2});
    }}>+</button>{count}
  1. 이것을 받는 reducer 작업
  • state를 return하는데 불변하게 코드를 다루기 위해서는 기존의 값에 복제를 해야함
function reducer(state, action) {
  if(action.type === 'up'){
  	return {...state, value:state.value + action.step}
  }
	return state;
}

최종코드

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

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

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></Counter>
        </div>
	  </Provider>
    );
}

개발환경 셋팅

  • create-reat-app 실행시 template으로 redux를 주면 자동으로 redux toolkit이 셋팅된 개발환경이 만들어짐
npx create-react-app my-app --template redux
  • 이미 존재하고 있는 것에 도입하고 싶다면 아래와 같은 명령어 주기
npm install @reduxjs/toolkit

Redux toolkit 적용한 코드

  • 기존에는 하나의 거대한 store 안에 모든 정보를 다 담음
  • 하지만 프로젝트가 커지만 기능별로 작은 store들을 만드는게 좋음
  • 작은 store = slice

  • 작은 store들을 합쳐서 Redux가 요구하는 큰 store로 Redux toolkit이 알아서 만들어줌

counter라는 기능을 위한 작은 store라고 할 수 있는 slice를 만들자

  • counter, timer 등을 각각의 기능별로 slice를 만들어서 하나의 store로 합치기
  1. slice 만들기
  • createSlice import하기
import {createSlice} from '@reduxs/tooltit';
  1. slice들은 필요한 객체들이 있음
  • slice 이름 정하기
  • 초기값 지정해주기
  • store reducers 공급해주기 (복수형 유의하기)
    - 여기에 타입별로 함수 정의해주기
    (기존 코드에서 if문으로 정의했던 부분)
  • 만들어진것을 counterSlice로 정의해주기
const CounterSlice = createSlice({
	name:'counter',
  	initialState:{valu:0},
  	reducers:{
    	up:{state, action} => {
        	state.value = state.value + action.step;
        }
    }
});
  1. 이렇게 작은 slice들을 모아서 store를 만들때는 configureStore 사용
  • import 해주기
  • configureStore에 객체 전달하기
    - 필수적으로 reducer 들어감 (reducers아님)
    • reducer에는 각각의 slice의 reducer가 들어가면 됨
    • counter state에 들어간 여러 reducer들을 (up 포함) 하나로 합쳐서 하나로 만든 reducer를 자동으로 만들어주는데, 그렇게 만들어진게 아래 코드counter:counterSlice.reducer의 reducer임
import { configureStore } from '@reduxjs/toolkit';

// 하나의 거대한 store
const store = configureStore({
	reducer:{
    	counter:counterSlice.reducer
    }
});
  • 만든 store를 Provider의 store로 전달하면 됨
  • store에서 사용하는 여러가지 정보들을(state) 사용하려면 useSelector를 사용하면 됨

action creater

  • redux toolkit에서는 reducer 함수들을 참고해서 자동으로 action을 만들어내는 action creater를 생성해줌
	dispatch(counterSlice.actions.up(2));
const CounterSlice = createSlice({
	name:'counter',
  	initialState:{valu:0},
  	reducers:{
    	up:{state, action} => {
        	state.value = state.value + action.payload;
        }
    }
});
  • 위 코드에서 action.step 대신 action.payload로 사용하면됨
profile
최강 개발자를 꿈꾸는 병아리

0개의 댓글