관리 메뉴

bright jazz music

생활코딩: Redux toolkit 본문

Framework/ReactJs

생활코딩: Redux toolkit

bright jazz music 2023. 5. 17. 18:57

 

1. redux toolkit 설치

/*기존  프로젝트에 리덕스 툴킷 설치*/
$npm install @reduxjs/toolkit 

/*새  프로젝트 생성 시 리덕스 툴킷 설치 */
$npx create-react-app test-app --template redux

 

 

2. App.js 작성 

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

//툴킷 임포트
import {configureStore, createSlice} from '@reduxjs/toolkit';


//슬라이스는 작은 store를 뜻한다. 여러 개 만들 수 있다.기존에는 하나의 store에 전부 집어넣었다. 리덕스 툴킷은 이러한 슬라이스들을 나중에 하나의 큰 store로 만든다.
const counterSlice = createSlice({
  name:'counterSlice', //슬라이스의 이름. 임의의 값을 정해준다.
  initialState:{value:0}, //기본 state 값(초깃값)
  //reducers: 복수형에 주의. counterSlice 안에는 다양한 슬라이스가 존재할 수 있다. up, down, reset, etc.
  reducers:{
    // type별로 함수 정의. action.type이 up일 때 처리해야 하는 reducer 생성
    up:(state, action)=>{
      // state.value = state.value + action.step;
      state.value = state.value + action.payload;
      console.log('###state.value', state.value);
    }
  }
});

const store = configureStore({ //슬라이스들을 합쳐주는 역할을 한다. 객체를 전달받아야 한다.
  reducer : {
    //리액트 툴킷은 여러 개의 리듀서를 하나로 만들어 준다. 그 결과가 counterSlice.reducer이다. 이 스토어를 다시 <Provider>의 store로 전달한다.
    //counterSlice의 리듀서 값 이름은 임의로 해도 된다. 여기서는 counter1으로 해줬다.
    counter1:counterSlice.reducer
  }
});

function Counter() {

  //useDispatch() : action 변경
  const dispatch = useDispatch(); 

   //useSelector(): state를 사용하여 표시
   const count = useSelector((state) => {
    console.log('##state', state);
    return state.counter1.value;
    //문제가 있음...
    // state.counter.value; // 반환문 추가
  });

  return (<div>
      <button onClick={()=>{
        // dispatch({type:'counterSlice/up', step:2}); //couterSlice라는 슬라이스의 리듀서에 속한 함수가 호출됨. 아래처럼 액션 크리에이터를 자동생성해서 쓸 수 있다.
        dispatch(counterSlice.actions.up(2)); //근데 이 때 파라미터가 payload라는 이름의 값으로 들어간다. 따라서 리듀서에서 step 대신 payload를 써야 한다.
      }}> + </button>
      {count}
    </div>
  )
}


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

 

============

 

파일 나누기

 

한 파일에 다 집어넣으면 사용이 어렵고 가독성이 떨어지기 때문에 나눈다.

아래와 같이 세 부분으로 나눈다,

 

  1. 슬라이스 ==> counterSlice.js
  2. 스토어 ==> store.js
  3. App(사용처) ==> App.js

 

1. counterSlice.js 작성

App.js에서도 counterSlice를 사용하기 때문에 counterSlice를 임포트 해야 한다.

액션은 간결히 쓰는 게 좋기 때문에 counterSlice.js에서 아래와 같이 익스포트 한다.

export const {up} = counterSlice.actions;

 

이렇게 하면 actions에 있는 이름들 중에 up이 익스포트 된다.

//툴킷 임포트: configureStore가 빠졌다. configureStore는 store.js에서 다룬다.
import {createSlice} from '@reduxjs/toolkit';


//슬라이스는 작은 store를 뜻한다. 여러 개 만들 수 있다.기존에는 하나의 store에 전부 집어넣었다. 리덕스 툴킷은 이러한 슬라이스들을 나중에 하나의 큰 store로 만든다.
const counterSlice = createSlice({
  name:'counterSlice', //슬라이스의 이름. 임의의 값을 정해준다.
  initialState:{value:0}, //기본 state 값(초깃값)
  //reducers: 복수형에 주의. counterSlice 안에는 다양한 슬라이스가 존재할 수 있다. up, down, reset, etc.
  reducers:{
    // type별로 함수 정의. action.type이 up일 때 처리해야 하는 reducer 생성
    up:(state, action)=>{
      // state.value = state.value + action.step;
      state.value = state.value + action.payload;
      console.log('###state.value', state.value);
    }
  }
});

//counterSlice라는 이름으로 export 해줬다. 사용측에서는 import {counterSlice} from './counterSlice'; 를 사용해서 import 해야한다.
//store에서 필요하기 때문에 ./store.js에서 import 해줬다.
export default counterSlice;


//dispatch(counterSlice.actions.up(2)); //에서도 사용하기 때문에 이것도 export 해줘야 한다.
//action의 경우 간결히 표현하자. up이라는 이름에 대해서, counterSlice의 actions 중에서 up이 export가 되는 것이다.
export const {up} = counterSlice.actions;

 

2. store.js 작성

//툴킷 임포트. createSlice가 빠쪘다. createSlice는 countSlice.js에서 다룬다.
import {configureStore} from '@reduxjs/toolkit';
import counterSlice from './counterSlice'; //.counterSlice : 슬라이스인 counterSlice를 포함하는 파일



const store = configureStore({ //슬라이스들을 합쳐주는 역할을 한다. 객체를 전달받아야 한다.
    reducer : {
      //리액트 툴킷은 여러 개의 리듀서를 하나로 만들어 준다. 그 결과가 counterSlice.reducer이다. 이 스토어를 다시 <Provider>의 store로 전달한다.
      //counterSlice의 리듀서 값 이름은 임의로 해도 된다. 여기서는 counter1으로 해줬다.
      counter1:counterSlice.reducer
    }
  });

  //파일을 분리하면서 export를 해줬다. 이렇게 해주면 임포트 하는 쪽에서 import store from './store'; 처럼 명시해 줄 수 있다.
export default store;

 

3. App.js

App.js에서도 counterSlice를 사용하기 때문에 counterSlice를 임포트 해야 한다.

액션은 간결히 쓰는 게 좋기 때문에 counterSlice.js에서 아래와 같이 익스포트 한다.

export const {up} = counterSlice.actions;

 

이렇게 하면 actions에 있는 이름들 중에 up이 익스포트 된다.

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

import store from './store'; //./store.js : store를 포함하는 파일
import {up} from './counterSlice'; //actions 중에서 up에 해당하는 것을 가져옴. 임포트하지 않으면 해당 액션이 없기 때문에 에러 발생


function Counter() {

  //useDispatch() : action 변경
  const dispatch = useDispatch(); 

   //useSelector(): state를 사용하여 표시
   const count = useSelector((state) => {
    console.log('##state', state);
    return state.counter1.value;
    //문제가 있음...
    // state.counter.value; // 반환문 추가
  });

  return (<div>
      <button onClick={()=>{
        // dispatch({type:'counterSlice/up', step:2}); //couterSlice라는 슬라이스의 리듀서에 속한 함수가 호출됨. 아래처럼 액션 크리에이터를 자동생성해서 쓸 수 있다.
        // dispatch(counterSlice.actions.up(2)); //근데 이 때 파라미터가 payload라는 이름의 값으로 들어간다. 따라서 리듀서에서 step 대신 payload를 써야 한다. 
        dispatch(up(2)); //{up}을 임포트 했으므로 up을 사용해 줘야 한다.
      }}> + </button>
      {count}
    </div>
  )
}


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

 

'Framework > ReactJs' 카테고리의 다른 글

1. React에서 axios 사용하기(GET)  (0) 2023.05.21
생활코딩: next.js  (0) 2023.05.18
생활코딩: react-redux 예제2  (0) 2023.05.17
생활코딩: react-redux 예제1  (0) 2023.05.17
생활코딩: useReducer  (0) 2023.05.16
Comments