Redux

고민경·2024년 11월 24일

Redux

  • Redux는 전역 데이터를 효과적으로 관리하는 라이브러리이다.
  • Redux는store 라는 독립적인 부분 딱 하나 존재하는데(단일 스토어), 어느 컴포넌트에서 store의 store에서 연관된 다른 컴포넌트를 render시킨다.

Actions(액션)

액션은 객체(Object)이다.
두 가지 형태의 액션이 존재한다.

  • type만 있는 액션: {type: 'TEST'}
    payload가 없는 액션, Action에서 전달할 특별한 값이 없는 경우
  • type과 payload가 있는 액션 {type: 'TEST', params: 'hello'} action에서 특별한 값을 전달하여 활용해야 하는 경우

type은 필수 property이고, string이다.
만들어진 action이 store에 전해지고 store의 상태를 변경하는 용도로 사용된다.

액션 생성자

  • action creator: 액션을 생성하는 함수
  • 함수를 통해 액션을 생성하해서, 액션 객체를 return한다.
  • 예) createTest('hello') => return { type: 'TEST', params: 'hello'}

액션이 하는 일

  • 액션 생성자를 통해 액션을 만든다. -> 액션 객체를 리덕스 스토어에 보낸다 -> 리덕스 스토어가 액션 객체를 받으면 스토어의 상태값이 변경된다 -> 변경된 상태 값에 의해 상태를 이용하고 있는 컴포넌트가 변경된다
  • 액션은 스토어에 보내는 일종의 인풋이라고 볼 수 있다

액션 준비

  • 액션의 타입을 정의하여 변수로 빼는 작업
  • 액션 객체를 만들어 내는 함수를 만드는 작업
// action.js
// type string 관리
export const ADD_TODO = "ADD_TODO";
// type의 경우 space는 underbar, 글자는 대문자로 사용한다. 

// addTodo의 매개변수가 todo임으로 todo property를 항상 가짐을 알 수 있다.
export function addTodo(todo) {
  	return {
      type: ADD_TODO,
      // todo: todo
      todo,
    };
}

Reducers(리듀서)

  • 액션을 주면, 그 액션이 적용되어 수정되거나 아닌 결과를 만들어주는 함수

  • Pure Function: 같은 input을 받으면 같은 결과를 내는 함수
    reducer 안에서 시간에 따라서 변하는 결과가 들어가면 안 된다.

  • Immutable: original State와 new State가 별도의 객체로 만들어져야 한다. (리덕스는 리듀서를 통해 state가 달라졌음을 Immutable 방식으로 인지한다)

    function reducerName(preState, action) {
        return newState;
    • 액션을 받아서 state를 리턴하는 구조
    • 인자로 들어오는 prevState와 리턴되는 newState는 다른 참조를 가지도록 해야 한다(Immutable해야 한다)
    // type 가져오기
      import { ADD_TODO } from "./actions";
    // state 구상 -> ['코딩', '점심 먹기']
    const initialState = [];
    
    export function todoApp(previousState = initialState, action) {
      // 초기값 설정 방법 01
      // if (previousState === undefined) {
      //   return [];
      // }
    
      // 초기값 설정 방법 02
      // 매개변수 자체에 initialState 값을 default 설정해 줌
    
      if (action.type === ADD_TODO) {
        // 배열 형태로 todo 값을 넣음
        return [...previousState, action.todo];
      }
    
      return previousState;
    }
    

createStore()

  • 스토어를 만드는 함수
    - `const store = createStore(리듀서)

    // store.js
    import { createStore } from "redux";
    import { todoApp } from "./reducers";
    
    const store = createStore(todoApp);
    
    export default store;
  • 스토어 함수 return 관련 함수
    - store.getState(): state를 가져오는 함수

    • store.dispatch(액션), store.dispatch(액션생성자()): 액션을 인자로 넣어서 store의 상태를 변경시킴
    • const unsubscribe = store.subscribe(() => {})
      • subscribe()는 state에 변경이 생겼을 때 안에 있는 callback을 실행시킴
        • return이 unsubscribe함수이다.
        • unsubscribe()하면 subscribe로 실행했던 함수가 이후부터는 제거된다.
        • store.replaceReducer: 원래 가지고 있던 reducer를 다른 reducer로 바꾸는 기능
    import React from "react";
    import ReactDOM from "react-dom";
    import App from "./App";
    
    // store와 action생성자를 가져옴
    import store from "./redux/store";
    import { addTodo } from "./redux/actions";
    
    // subscribe : 스토어의 상태가 변경되면 함수가 호출됨
    // 그리고 unsubscribe의 함수를 return 함
    const unsubscribe = store.subscribe(() => {
      console.log(store.getState());
    });
    
    // dispatch : state를 변경 함
    store.dispatch(addTodo("coding"));
    store.dispatch(addTodo("Read Books"));
    store.dispatch(addTodo("eat"));
    unsubscribe();
    // 이후에는 subscribe에 있는 함수가 실행안됨 (store 변경은 그대로 이루어짐)
    store.dispatch(addTodo("coding"));
    store.dispatch(addTodo("Read Books"));
    store.dispatch(addTodo("eat"));
    
    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById("root")
    );

    정리

  • Action 만들기

    • Action 생성자 함수 만들기(Type 결정)
    • Type이 필요함
    • Action에 데이터가 들어간다
  • Reducer 만들기

    • Reducer 생성 함수 만들기
    • Type을 가져와서 만든다
    • Type을 기준으로 action을 받아 state를 변경할지 결정하는 로직
  • Store 만들기

    • createStore(reducer)로 단일 store를 만든다
    • 어떤 reducer 로직으로 store 만들건지 결정한다
  • Store 활용하기

    • dispatch(Action): state 변화시키기
    • subscribe(callback): state 변화 시에 실행할 callback
    • unsubscribe(): (subscribe의 return): subscribe의 callback 중지

0개의 댓글