본문 바로가기
Frontend/React

[React] Redux(1) [count 만들기]

by pin9___9 2022. 12. 13.
728x90

Redux란?

리덕스는 리액트에서 가장 많이 사용되는 상태 관리 라이브러리중 하나이다. 리덕스를 사용하면 컴포넌트의 상태 업데이트 관련 로직을 다른 파일로 분리시켜서 효율적으로 관리할 수 있다. 최근 Redux Toolkit이 등장하면서 더욱 더 이 효율성은 빛을 보이고 있다.

 

Redux 기본 키워드

1. 액션( Action )

  • 상태에 어떠한 변화가 필요하게 도리 때, 액션이란 것을 발생시켭니다. 액션은 객체로 표현되며 type필드를 반드시 가지고 있어야 합니다.
{
    type : "PLUS_ONE"
}

 

2. 액션 생성함수( Action Creator )

  • 액션 생성함수는, 액션을 만드는 함수입니다. 
  • 액션 생성함수를 만들어서 사용하는 이뉴는 나중에 컴포넌트에서 더욱 쉽게 액션을 발생시키기 위함입니다. 
  • 그래서 보통 함수 앞에 export 키워드를 붙여서 다른 파일에서 불러와 사용합니다.

*리덕스를 사용 할 때 액션 생성함수를 사용하는 것이 필수적이진 않습니다.

 

export function addTodo(data) {
  return {
    type: "ADD_TODO",
    data
  };
}

// 화살표 함수로도 만들 수 있습니다.
export const changeInput = text => ({ 
  type: "CHANGE_INPUT",
  text
});

 

3. 리듀서( Reducer )

  • 리듀서는 변화를 일으키는 함수입니다. 리듀서는 현재 상태와 액션 객체를 받아 필요하다면 새로운 상태를 리턴하는 함수입니다.
  • 액션 유형을 기반으로 이벤트를 처리하는 이벤트 리스너라고 생각하면 됩니다.
const counter = (state = initialState, action) => {
  switch (action.type) {
    case "PLUS_ONE":
      return { number: state.number + 1 };
    case "MINUS_ONE":
      return { number: state.number - 1 };
    default:
      return state;
  }
};

 

4. 스토어( Store )

  • 리덕스에서 한 애플리케이션 당 하나의 스토어를 가질 수 있습니다. 
  • 스토어 안에는 현재의 애플리케이션의 상태와, 리듀서가 들어가 있고 추가적으로 몇가지 내장 함수들이 있습니다.

 

5. 디스패치( Dispatch )

  • 디스패치는 스토어의 내장함수 중 하나입니다.
  • 액션 객체를 넘겨줘서 상태를 업데이트 하는 유일한 방법입니다.
  • 디스패치 함수에는 액션을 파라미터로 전달합니다. *dispatch(action) 
  • 이벤트 트리거

 

6. 구독( Subscribe )

  • 구독 또한 스토어의 내장함수 중 하나입니다.
  • subscribe 함수는, 함수 형태의 값을 파라미터 값으로 받아옵니다.
  • subscribe 함수에 특정 함수를 전달하면, 액션이 디스패치 되었을 때 마다 전달해준 함수가 호출합니다.
  • 이벤트 리스너

리덕스를 사용할 때 보통 이 함수를 직접 사용하는 일은 거의 없고, 대신 react-redux라는 라이브러리에서 제공하는 connect 함수 또는 useSelector Hook을 사용하여 리덕스 스토어 상태에 구독합니다.

 

Redux 상태 흐름

1. View 에서 액션이 일어난다.
2. dispatch 에서 action이 일어나게 된다.
3. action에 의한 reducer 함수가 실행되기 전에 middleware가 작동한다.
4. middleware 에서 명령내린 일을 수행하고 난뒤, reducer 함수를 실행한다.
5. reducer 의 실행결과 store에 새로운 값을 저장한다.
6. store의 state에 subscribe 하고 있던 UI에 변경된 값을 준다.

 

counter 만들기

1. redux와 react-redux 다운받기

yarn add redux react-redux

 

 

2. counter.js 만들기

// 초기 상태값
const initialState = {
  number: 0,
};

// 리듀서 : 변화를 일으키는 함수
const counter = (state = initialState, action) => {
  console.log(action);
  switch (action.type) {
    case "PLUS_ONE":
      return { number: state.number + 1 };
    case "MINUS_ONE":
      return { number: state.number - 1 };
    default:
      return state;
  }
};

// 모듈파일에서는 리듀서를 export default 한다.
export default counter;

 

3. configStore.js 로 App.js와 counter.js를 묶기

import { createStore } from "redux";
import { combineReducers } from "redux";
import counter from "../modules/counter";

const rootReducer = combineReducers({
  counter: counter,
});
const store = createStore(rootReducer);

export default store;

 

4. index.js에 추가하기

// 원래부터 있던 코드
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

// 우리가 추가할 코드
import store from "./redux/config/configStore";
import { Provider } from "react-redux";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  //App을 Provider로 감싸주고, configStore에서 export default 한 store를 넣어줍니다.
  <Provider store={store}>
    <App />
  </Provider>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 

5. App.js 에 버튼과 카운딩되는 숫자 코딩하기

// src/App.js

import React from "react";
import { useSelector, useDispatch } from "react-redux"; // import 해주세요.

const App = () => {
  const dispatch = useDispatch();
  const number = useSelector((state) => state.counter.number);

  return (
    <div>
      {number}
      <button
        onClick={() => {
          dispatch({ type: "PLUS_ONE" });
        }}
      >
        +1
      </button>
      <button
        onClick={() => {
          dispatch({ type: "MINUS_ONE" });
        }}
      >
        -1
      </button>
    </div>
  );
};

export default App;

 

728x90

'Frontend > React' 카테고리의 다른 글

[React] React-Router-Dom  (0) 2022.12.15
[React] Redux(2) [payload]  (0) 2022.12.14
[React] 절대 경로 (Absolute Imports)  (0) 2022.08.19
[React] React useState 공부하기!  (0) 2022.08.18
[React] React Hooks 공부하기!  (0) 2022.08.13

댓글