• 티스토리 홈
  • 프로필사진
    redpome
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
redpome
  • 프로필사진
    redpome
    • 분류 전체보기 (50)
      • 내일배움캠프 (23)
      • 웹개발 지식 (2)
      • 프로그래머스 (8)
      • React (7)
      • 코딩테스트 (1)
      • UI-UX (1)
      • 타입스크립트 (2)
      • Next.js (3)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • Redux, RTK 사용법 정리 - (1)
        2025년 02월 07일
        • redpome
        • 작성자
        • 2025.02.07.:23

        머릿속에 남을려면 내가 정리를 해야한다. 사용법을 익힐겸 정리해보자.



        Redux 개념

        Context API를 통해서 컴포넌트에서 전역으로 상태를 관리하는 방법을 학습했었다. Context API는 Provider로 감싸고 컴포넌트내에서 필요한 데이터를 사용하도록 설계되었지만 사용한 컴포넌트의 하위 컴포넌트에서는 리렌더링이 발생하게 될 수 있다. 이는 성능최적화 문제에 맞닥뜨리게되고 리덕스는 상태 변경을 필요로하는 컴포넌트에서만 업데이트를 발생시킨다.

         

        Store

        리덕스에서는 Store라는 하나의 저장소에서 상태를 관리한다. 중앙에서 관리하는 상태 변경은 Reducer에 의해 처리된다. 리덕스는 이런 중앙 state 관리소를 사용할 수 있는 라이브러리라 할 수 있다. store라는 디렉터리를 생성하고, modules, config 디렉터리도 만들어서 관리한다.


        여기에서 내가 쓸 state라는 것은 modules 디렉터리에 존재한다. useState의 사용을 파일단위로 확장시켜 사용한다고 생각하자, 파일 전체가 useState 선언을 한 것과 다름없다.

        config는 환경 설정을 위한 것으로 다음의 코드와 같이 선언하고 사용하자.

        import { createStore } from "redux";
        import { combineReducers } from "redux";
        import todos from "../modules/todos";
        
        const rootReducer = combineReducers({
          todos,
        });
        const store = createStore(rootReducer);
        export default store;


        todo 리스트를 Redux를 사용하여 구성해보자.

        import TodoListContainer from "./components/TodoListContainer";
        import AddForm from "./components/AddForm";
        const App = () => {
          return (
            <div>
              <AddForm />
              <TodoListContainer />
            </div>
          );
        };
        
        export default App;


        App.jsx의 컴포넌트 구성은 위와 같고, AddForm에서 입력을, TodoListContainer에서 todos의 내용을 렌더링한다.

        우선 modules에 생성한 todo의 내용을 살펴보자

         

        const ADD_TODO = "ADD_TODO";
        
        export const addTodo = (payload) => {
          return { type: ADD_TODO, payload };
        };
        //리덕스에서 모듈 파일은 
        const initialState = {
          todos: [
            {
              id: 1,
              title: "redux practice",
            },
          ],
        };
        const todos = (state = initialState, action) => {
          switch (action.type) {
            case ADD_TODO:
              return {
                ...state,
                todos: [...state.todos, action.payload],
              };
            default:
              return state;
          }
        };
        export default todos;

         

        모듈에서 생성한 todo는 액션이다. 

         

        const ADD_TODO = "ADD_TODO";
        
        export const addTodo = (payload) => {
          return { type: ADD_TODO, payload };
        };


        action을 생성하는 함수로서 addTodo 함수를 정의하였다. addTodo는 {type: ADD_TODO, payload } 객체를 반환하는 함수이고 payload는 todo 데이터가 들어가게된다. 이를 action creator라 한다.

         

        const todos = (state = initialState, action) => {
          switch (action.type) {
            case ADD_TODO:
              return {
                ...state,
                todos: [...state.todos, action.payload],
              };
            default:
              return state;
          }
        };

         

        정의한 todos는 Reducer의 역할을 한다. state를 변경하고 action.type에 따라 상태를 업데이트한다.
        ADD_TODO라는 액션 타입에 경우에 이전에 존재하는 todos 배열을 [...state.todos] -> 새로운 배열로 복사하고, action.payload를 추가한다.

        Reducer는 상태와 액션을 인자로 받아 새로운 상태를 반환한다고 할 수 있다.

         

        import { useDispatch } from "react-redux";
        import { addTodo } from "../redux/modules/todos";
        import { useState } from "react";
        import styled from "styled-components";
        
        const AddForm = () => {
          const [title, setTitle] = useState("");
          const dispatch = useDispatch();
        
          const onSubmitHandler = (e) => {
            e.preventDefault();
            if (title === "") return;
        
            dispatch(
              addTodo({
                id: new Date().getTime(),
                title,
              })
            );
          };
          return (
            <StFormContainer>
              <form onSubmit={onSubmitHandler}>
                <label>Type the title</label>
                <StInput
                  type="text"
                  value={title}
                  onChange={(e) => setTitle(e.target.value)}
                />
                <StButton>Add</StButton>
              </form>
            </StFormContainer>
          );
        };
        
        export default AddForm;


        AddForm 컴포넌트에서 사용자의 입력을 처리하는 코드이다. 여기서는 todos 모듈을 호출하고 useDispatch라는 store 내장 함수를 호출하여 해당 컴포넌트에서 store로부터 이벤트를 수행하려한다.


        const AddForm = () => {
          const [title, setTitle] = useState("");
          const dispatch = useDispatch();
        
          const onSubmitHandler = (e) => {
            e.preventDefault();
            if (title === "") return;
        
            dispatch(
              addTodo({
                id: new Date().getTime(),
                title,
              })
            );
          };


        dispatch는 함수다, onSubmitHandler 함수는 dispatch 함수를 통해 addTodo라는 액션을 store에 전달한다.

        위의 컴포넌트에서 흐름은 다음과 같다.

         

        1. title에는 사용자가 입력한 상태가 저장된다.
        2. onSubmitHandler 함수는 dispatch 함수를 실행시킨다.
        3. dispatch 함수는 store로 addTodo 액션을 전달한다.
        4. store에 있는 reducer는 전달받은 action의 type을 통해 정해진 기능을 수행한다.
        5. 상태가 변경되고 리렌더링이 실행된다.

        정리

        Redux의 사용과 개념을 정리해보자

         

        • Action : 객체를 통해 정의하는 동작, type을 통해 action의 종류를 정의한다.
        • Dispatch : Strore의 내장 함수로 Action을 Reducer로 보내는 함수이다.
        • Reducer : 디스패치가 전달한 액션객체의 type에 따라 상태를 변경시킨다

         

        TodoList Redux로 구현해보기

         

        추가와 삭제함수만 만들어보자. 우선 삭제함수를 만들기 위한 순서는 다음처럼 정했다.

         

        1. todos라는 모듈에서 DELETE_TODO 라는 action 정의
        2. Reducer에서 DELETE_TODO라는 액션의 실행 기능 정의
        3. List 컴포넌트에서 삭제 함수 정의
        4. useDispatch, todo모듈에서 delteTodo action 호출
        5. onDeleteHandler 함수 정의한 후 dispatch로 deleteTodo 액션에 삭제할 id를 매개변수로 전달
        const DELETE_TODO = "DELETE_TODO";
        
        export const deleteTodo = (payload) => {
          return { type: DELETE_TODO, payload };
        };
        
        
        const todos = (state = initialState, action) => {
          switch (action.type) {
            case DELETE_TODO:
              return {
                ...state,
                todos: state.todos.filter((todo) => todo.id !== action.payload.id),
              };
            default:
              return state;
          }
        };
        export default todos;

         

         

        위와 같이 todos 모듈에서는 action을 정의하고 reducer에는 해당 액션의 기능을 정의했다.

         

         

        import { useSelector, useDispatch } from "react-redux";
        import { deleteTodo } from "../redux/modules/todos";
        
        const TodoListContainer = () => {
          const { todos } = useSelector((state) => state.todos);
          const dispatch = useDispatch();
          const onDeleteHandler = (id) => {
            dispatch(deleteTodo({ id }));
          };
          //store에 있는 todos 모듈에서 상태를 선택한다
          return (
            <StTodos>
              {todos.map((todo) => (
                <StTodo key={todo.id}>
                  {todo.title}
                  <DeleteBtn onClick={() => onDeleteHandler(todo.id)}>DELETE</DeleteBtn>
        			...

         

        todos의 목록을 생성하는 컴포넌트에서 삭제 버튼 컴포넌트를 생성하고 해당 버튼을 누르면 onSubmitHandler를 통해 액션을 디스패치를 통해 전달하도록했다.

        모듈에 있는 deleteTodo action을 호출하고 디스패치는 해당 id를 매개변수로 가지고 있는 액션을 리듀서로 전달한다.

        'React' 카테고리의 다른 글

        Redux, RTK 사용법 정리 - (2)  (0) 2025.02.10
        React hooks(1)  (0) 2025.01.27
        투두 리스트 복기  (1) 2025.01.24
        개인과제 회고 - 올림픽 메달 기록  (0) 2025.01.22
        리액트 리스트 추가 및 생성  (1) 2025.01.22
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바