본문 바로가기
IT 공부/React

리액트 리덕스 실전 사용 (모달편)

by 쭈잇 2024. 12. 11.

Contents

    반응형

    리덕스는 애플리케이션 전역상태 관리 라이브러리

     

    모달 창을 띄우는 것, 제거하는 것 등을 리덕스로 관리해보자

     

    리덕스 기본 개념

    1. state : 애플리케이션 데이터나 UI 상태 저장. => store

    2. action : 상태를 바꾸기 위해 발생하는 이벤트 => ex) 모달  띄우기, 모달 끄기

    3. reducer : 액션 처리, 새로운 상태 반환 함수

     

    리덕스는 상태를 한군데에서 관리하고, 그 상태를 다른 곳에서 쉽게 사용할 수 있게 한다

     

    dispatch 란? (시키는 애)

    액션을 발생시키는 애!. 이거 해줘!! 라고 말하는 애 (시키는 애)

    dispatch({ type: 'GET_APPLE' })

    reducer란? (새로운 거 반환 해주는, 행동자)

    상태를 변경하는 규칙서. 현재 상태와 액션을 받아 새로운 상태를 반환!

    function reducer(state, action) {
      if (action.type === 'GET_APPLE') {
        return { apples: state.apples + 1 }; // 상태 업데이트
      }
      return state; // 다른 액션이면 그냥 기존 상태 유지
    }

     

    Redux의 흐름

    1. Action → 요청서: "새로운 데이터를 추가해 주세요!"
    2. Dispatch → 요청서를 접수하는 애
    3. Reducer → 요청서를 검토해서 데이터를 수정하는 관리자.
    4. Store → 모든 데이터를 저장하는 창고.
    5. useSelector → 창고에서 필요한 데이터를 가져오는 창구.


    useEffect와 dispatch 함께 사용하기

    useEffect는 컴포넌트가 렌더링될 때 특정 작업을 실행하개 해줌
    dispatch를 함께 사용하면 컴포넌트가 처음 렌더링될 때 특정 액션을 실행할 수 있다

     

    import React, { useEffect } from 'react';
    import { useDispatch, useSelector } from 'react-redux';
    
    const Counter = () => {
      const dispatch = useDispatch(); // Redux에게 명령을 보낼 준비
      const count = useSelector((state) => state.counter.value); // Redux에서 상태 가져오기
    
      useEffect(() => {
        // 컴포넌트가 처음 화면에 나타날 때 실행
        dispatch({ type: 'FETCH_INITIAL_COUNT' }); // 초기 숫자를 가져오라는 요청 보내기
      }, [dispatch]); // useEffect가 dispatch에 의존
    
      return <p>Count: {count}</p>; // 가져온 숫자를 표시
    };

     

     

     

    # 스토어 

    애플리케이션 상태를 관리할 스토어를 설정한다. 

    애플리케이션 모든 상태가 저장되어 있는 곳

    리듀서와 액션을 연결해서 상태를 업데이트한다 

    1. 리덕스 스토어 설정하기

    먼저 리듀서

    // modalSlice.js (리덕스 slice 파일)
    import { createSlice } from '@reduxjs/toolkit'
    
    // 모달 상태의 초기값
    const initialState = []
    
    const modalSlice = createSlice({
      name: 'modal', // slice의 이름
      initialState, // 초기 상태는 빈 배열
      reducers: {
        // 모달을 추가하는 액션
        addModal: (state, action) => {
          return [...state, action.payload]
        },
        // 모달을 제거하는 액션
        removeModal: (state, action) => {
          return state.filter(modal => modal.modalId !== action.payload)
        },
      },
    })
    
    // 액션을 export해서 컴포넌트에서 사용할 수 있도록 함
    export const { addModal, removeModal } = modalSlice.actions
    
    // 리듀서 export
    export default modalSlice.reducer

    모달 열고, 닫고의 2가지 액션만 정의

    2. 스토어에 리듀서 연결하기

    // store.js
    import { configureStore } from '@reduxjs/toolkit'
    import modalReducer from './modalSlice'
    
    export const store = configureStore({
      reducer: {
        modal: modalReducer, // modalSlice를 스토어에 연결
      },
    })

    이러면 리덕스 스토어에서 modal 상태를 관리할 수 있다

     

    3. useModal 훅 만들기

    모달을 추가, 제거하는 로직을 간편하게 사용하기 위해 useModal을 만든다

    // useModal.js
    import { useDispatch } from 'react-redux'
    import { addModal, removeModal } from './modalSlice'
    import { generateUUID } from 'your-uuid-generator'
    
    const useModal = () => {
      const dispatch = useDispatch()
    
      const addModalAction = (modal) => {
        dispatch(
          addModal({
            ...modal,
            modalId: generateUUID(), // 고유한 ID를 부여
          })
        )
      }
    
      const removeModalAction = (modalId) => {
        dispatch(removeModal(modalId))
      }
    
      return { addModal: addModalAction, removeModal: removeModalAction }
    }
    
    export default useModal

    이 훅에서는 addModal, removeModal 을 사용해 리덕스 스토어에 모달을 추가하거나 제거하는 기능을 제공한다

     

    4, 모달 컴포넌트 사용

    리덕스 스토어에서 modal 사용을 받아와 모달을 렌더링

    // ModalComponent.js
    import React, { useEffect } from 'react'
    import { useSelector } from 'react-redux'
    import { useModal } from './useModal'
    import { AlertPopup } from '../Popup'
    
    const ModalComponent = () => {
      const modalData = useSelector((state) => state.modal) // 리덕스 스토어에서 모달 상태 가져오기
      const { removeModal } = useModal()
    
      useEffect(() => {
        if (modalData.length > 0) {
          const timer = setTimeout(() => {
            removeModal(modalData[0].modalId) // 3초 후 모달 닫기
          }, 3000)
          
          return () => clearTimeout(timer) // cleanup
        }
      }, [modalData, removeModal])
    
      return (
        <>
          {modalData.length > 0 && (
            <AlertPopup
              title={modalData[0].title}
              content={modalData[0].content}
              open={true}
            />
          )}
        </>
      )
    }
    
    export default ModalComponent

    useSelector 로 리덕스스토어에서 모달상태 가져옴

    • 상태가 변경되면 useSelector를 사용한 컴포넌트들이 자동으로 새 데이터를 받음
    • 예: 모달 추가 후, 컴포넌트가 자동으로 다시 렌더링됩니다.
    import React, { useEffect } from 'react'
    import { useModal } from './useModal'
    
    const Lng = () => {
      const { addModal } = useModal()
    
      useEffect(() => {
        // 예시: 모달을 띄우기 위한 조건이 충족되었을 때
        addModal({
          type: 'VIEW',
          title: '코딩',
          content: '싫어',
          autoClose: 2, // 3초 후 모달 자동 닫기
        })
      }, [addModal])
    
      return <div>집 가고 싶다</div>
    }
    
    export default Lng

     

    슬라이스가 뭐야?

    애플리케이션 기능의 특정 부분과 관련된 상태나 리듀서 및 작업의 모음.

    유지 관리성과 확장성을 위해 리덕스 코드를 구성하고 모듈화하는데 도움이 된다함!

    Redux Toolkit 이용해서 상용구 코드 수동으로 작성 안해도 돼서 편하게 슬라이스 생성가능

     

    • State: 슬라이스가 담당하는 전역 리덕스 상태의 일부
    • Reducers: 특정 작업에 대한 응답으로 상태를 업데이트 하는 방법을 정의
    • Actions: 상태 업데이트 트리거하는 명명된 이벤트 
    • Action Creators: 리듀서 트리거하기 위해 전달될 수 있는 자동으로 생성된 함수

    1. Initial State

    상태의 초기값을 정의

    2. Reducers

    상태를 업데이트하는 함수들의 집합

    3. Exported Actions and Reducer

    Redux Toolkit은 각 리듀서에 대한 액션 생성자를 자동으로 생성하며, 이 슬라이스에 대한 결합된 리듀서 기능도 제공



    참고) 챗지피티

     

    반응형

    'IT 공부 > React' 카테고리의 다른 글

    React 기초, Component  (3) 2024.11.30
    React에서 JSX사용, state 변경  (6) 2024.11.21
    React 기초, 리액트란  (3) 2024.11.21