TIL #29 | Context 및 Redux로 리팩토링하기

kibi·2023년 11월 20일
1

TIL (Today I Learned)

목록 보기
28/83

React Router 리다이렉트

<Navigate> 요소는 렌더링될 때 현재 위치를 변경한다.
https://reactrouter.com/en/6.19.0/components/navigate

<Route path="*" element={<Navigate replace to="/" />} />

context 리팩토링

1) context 폴더 및 파일 생성

2) 사용할 전역 데이터 구성

// LetterContext.js
import { createContext, useState } from "react";
import fakeData from "fakeData.json";

export const LetterContext = createContext(null);

function LetterContextProvider(props) {
  const [letterList, setLetterList] = useState(fakeData);

  return (
    <LetterContext.Provider value={{ letterList, setLetterList }} {...props} />
  );
}

export default LetterContextProvider;
// MemberContext.jsx
import { createContext, useState } from "react";

export const MemberContext = createContext(null);

function MemberContextProvider(props) {
  const [selectedMember, setSelectedMember] = useState("");

  return (
    <MemberContext.Provider
      value={{ selectedMember, setSelectedMember }}
      {...props}
    />
  );
}

export default MemberContextProvider;

3) 생성한 Provider로 전역 데이터를 사용할 하위 컴포넌트를 감싸준다.

import LetterContextProvider from "context/LetterContext";
import MemberContextProvider from "context/MemberContext";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <MemberContextProvider>
    <LetterContextProvider>
      <App />
    </LetterContextProvider>
  </MemberContextProvider>
);

4) useContext로 데이터 가져오기

  • 구조분해할당으로 값을 가져올 수 있다.
  const { letterList, setLetterList } = useContext(LetterContext);
  const { setSelectedMember } = useContext(MemberContext);

Redux로 리팩토링

yarn add redux react-redux

  1. 리듀서 함수 만들기 (모듈화 시켜서 관리)

  2. 스토어 설정

import { createStore, combineReducers } from "redux";
import letters from "redux/modules/letters";
import member from "redux/modules/member";

const rootReducer = combineReducers({ letters, member });

const store = createStore(rootReducer);

export default store;
  1. 리듀서 모듈 구현

액션 생성자

const ADD_LETTER = "letters/ADD_LETTER";

const DELETE_LETTER = "letters/DELETE_LETTER";

const EDIT_LETTER = "letters/EDIT_LETTER";

사용할 함수 구현

export const addLetter = (payload) => {
  return { type: ADD_LETTER, payload };
};
export const deleteLetter = (payload) => {
  return { type: DELETE_LETTER, payload };
};
export const editLetter = (payload) => {
  return { type: EDIT_LETTER, payload };
};

액션 객체 실행시 타입에 따른 로직 구현

const initialState = fakeData;

const letters = (state = initialState, action) => {
  switch (action.type) {
    case ADD_LETTER:
      const newLetter = action.payload;
      return [newLetter, ...state];
    case DELETE_LETTER:
      const letterId = action.payload;
      return state.filter((letter) => letter.id !== letterId);
    case EDIT_LETTER:
      const { id, editContent } = action.payload;
      return state.map((letter) => {
        if (letter.id === id) {
          return { ...letter, content: editContent };
        }
        return letter;
      });
    default:
      return state;
  }
};

export default letters;

provider

import { Provider } from "react-redux";
import store from "redux/config/configStore";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

상태 가져오기 : useSelector

상테 요청하기 : dispatch

0개의 댓글