티스토리 뷰

개발../React

Redux

링재호 2021. 10. 3. 17:51

Redux

  • state 종속성 탈피 (컴포넌트에 종속되지 않고 store 라는 곳에 state 형태로 저장함. state 가 변결되면 해당 state 를 바라보고 있는 컴포넌트는 모두 리렌더링 됩니다.)
  • props depth 해결방법. 심지어 리액트는 단방향이기 때문에 Vue 처럼 부모로 올리기가 어렵습니다.
  • action(dispatch 함수 이름) => dispatch(store 에 state 를 변경하는 함수) => store(state 변화) => view(리렌더링) 흐름으로 flux 패턴을 따릅니다.

설치

yarn add redux react-redux redux-devtools-extension redux-logger

용어

Action: 객체 형식으로 이루어져 있고, type 을 가지고 있음.
Action Function: 파라미터를 받아와 액션 객체 형태로 만들어주는 함수.
Reducer: 이전 상태와 Action 을 받아 새로운 state 객체를 만드는 함수.

Hooks

UseDispatch: 액션을 발생 시켜 파라미터를 전달하여 액션을 생성합니다.
UseSelector: 현재 store 에 저장된 state를 가져올 수 있습니다. (꺼내온다.)

Example

예제는 React-Router 예제에서 했던 내용을 그대로 사용하겠습니다.
sample1, sample2, sample3 페이지를 props 를 넘기지 않고, 하나의 컴포넌트로 관리하도록 만들어보겠습니다.

index.js: 루트 리듀서를 받아 스토어를 생성해줍니다.
생성하는 것은 굳이 이해 안하셔도 됩니다. (이렇게 사용하라고 해서 사용하는 것일 뿐...)

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
// Redux-start
import {
  legacy_createStore as createStore,
  applyMiddleware,
  compose,
} from "redux";
import { Provider } from "react-redux";
import logger from "redux-logger";
import { composeWithDevTools } from "redux-devtools-extension";
import rootReducer from "./reducers";
// Redux-end

// 배포 레벨에서는 리덕스 발동시 찍히는 logger를 사용하지 않습니다.
const enhancer =
  process.env.NODE_ENV === "production"
    ? compose(applyMiddleware())
    : composeWithDevTools(applyMiddleware(logger));

// 위에서 만든 reducer를 스토어 만들때 넣어줍니다
const store = createStore(rootReducer, enhancer);
const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

// 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(console.log);

리듀서 (reducer/index.js) 를 만들어봅시다.

initState: 초기 상태
CreateSample: Sample 이 만들어지면 액션을 만들 함수

const CRATE_SAMPLE = 'CREATESAMPLE';

// init
const initState = {
  name: '',
  desc: ''
};

// action function
export const CreateSample = (name, desc) => {
  return {
    type: CRATE_SAMPLE,
    name,
    desc
  };
}

// Reducer
function rootReducer (state = initState, action) {
  switch (action.type) {
    case CRATE_SAMPLE:
      return {
        ...state,
        name: action.name,
        desc: action.desc
      };
    // default를 쓰지 않으면 맨처음 state에 count값이 undefined가 나옵니다 꼭! default문을 넣으세요
    default:
      return state;
  }
}

export default rootReducer;

sample1.js (src/sample/sample1.js)
CreateSample 액션 함수를 가져와 name, desc 파라미터를 넘겨 액션 객체를 생성합니다.

import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { CreateSample } from '../reducer';
import Contents from './contents';

const Sample1 = () => {
  const dispatch = useDispatch();
  const name = 'Sample1';
  const desc = '첫번째 샘플 페이지입니다.';

  useEffect(() => {
    dispatch(CreateSample(name, desc));
  }, []);

  return (
    <Contents />
  );
};

export default Sample1;

contents.js (src/sample/contents.js) 를 하나 만들어줍시다.
useSelector 를 이용하여 store 에 저장된 name, desc 객체를 가져와 화면에 뿌립니다.
이런 식으로 props 를 넘기지 않고, 객체를 관리할 수 있습니다.
나머지 샘플페이지도 이런 식으로 만들어보자.

import React from 'react';
import { useSelector } from 'react-redux';

const Contents = () => {
  const name = useSelector(state => state.name);
  const desc = useSelector(state => state.desc);

  return (
    <div>
      <h1>{ name }</h1>
      <p>{ desc }</p>
    </div>
  );
};

export default Contents;

경험

화면에 전역객체에 상태를 보고 각 컴포넌트에 기능을 넣을려고 방법을 찾던 와중에 Redux 라는 라이브러리를
발견하였다. 기존 프로젝트에 리덕스 라이브러리를 사용하였고, props 단위로 넘기던 코드들을 리팩토링하여
관리하는데 용이해졌고, 원하던 기능 또한 쉽게 개발할 수 있었다.

'개발.. > React' 카테고리의 다른 글

React 생명주기 (lifecycle)  (0) 2022.01.25
Next.js  (0) 2021.11.15
React-Router  (0) 2021.10.02
React Hooks 란?  (0) 2021.09.25
React  (0) 2021.09.11
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함