ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [메인프로젝트] Redux 사용하여 NavBar 컴포넌트 구현
    IT/회고 2023. 8. 30. 10:31

    Redux를 사용하여 상태를 관리하는 기능을 가지고,

    좌측에 위치해서 메뉴 네비게이션 바의 역할을 하는 컴포넌트를 만들어봅시다.

     

     

    1. 리액트라우터 설치

    npm install react-router-dom

     

     

    2. 브랜치 정리

    main / dev / fe / feat/NavBar 순서로 됩니다

    fe에서 pull 하려면 현재 작업하던 브랜치(feat/NavBar)에서 git pull origin fe 하면 됩니다.

     

    main

      ㄴdev

         ㄴ fe

          |     - feat/NavBar

         ㄴ be

     

     

     

     

     

    3. Redux 개념

    Redux를 사용하려면 redux와 @reduxjs/toolkit( 줄여서 RTK ) 패키지, 리액트에서 사용할 거라면 react-redux 패키지를 설치해야 합니다.

     

     

    1) Provider 컴포넌트

    리덕스 기능을 사용하려면 리액트 컨텐스트의 Provider 컴포넌트가 최상위로 동작해야 합니다.

    import { Provider } from 'react-redux';

     

     

    2) 스토어 객체 관리 함수

    RTK 패키지는 리듀서에서 반환한 새로운 상태를 store 라는 객체로 정리해 관리하는 configurestore 함수를 제공합니다.

    import { configureStore } from '@reduxjs/toolkit';

     

     

    3) useSelector 훅

    리덕스 저장소에 어떤 내용이 저장되었는지 알고자 스토어의 상탯값을 반환해줍니다.

    import { useSelector} from 'react-redux';

     

     

    4) useDispatch 훅

    useDispatch를 호출하면 dispatch() 함수를 얻을 수 있습니다. 이 함수를 사용하여 리덕스 저장소에 저장된 객체의 멤버 전부나 일부를 변경할 수 있습니다.

    import { useDispatch } from 'react-redux';
    
    const dispatch = useDispatch();

     

     

    5) dispatch함수와 리듀서 간의 관계

    dispatch(액션) -> 리듀서 -> 리덕스 저장소

     

    function reducer(state, action)에서 state는 리덕스 저장소, action은 dispatch(액션)을 의미한다.

     

     

     

     

     

    4. Redux 사용해서 active된 메뉴 저장하기

     

    index.js

    // index.js
    
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import App from './App';
    import { Provider } from 'react-redux';
    import { configureStore } from '@reduxjs/toolkit';
    import menuSliceReducer from './store/menuSlice';
    
    
    // 스토어를 구성합니다.
    const store = configureStore({
      reducer: {
        menu: menuSliceReducer, // 'menu'라는 키에 menuSliceReducer를 설정합니다.
        // 다른 리듀서도 필요한 경우 추가할 수 있습니다.
      },
    });
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <React.StrictMode>
        <Provider store={store}>
             <App /> 
        </Provider>
      </React.StrictMode>
    );

     

     

     

     

    NavBar.jsx

    useSelecor 훅을 사용하여 Redux 스토어에 selectActiveMenu 를 가져와 현재 활성화 된 메뉴를 가져옵니다.

      const activeMenu = useSelector(selectActiveMenu);

     

    메뉴 클릭 핸들러를 하나 만들어서 클릭된 메뉴의 이름을 받아와 redux 스토어에 해당 메뉴를 활성화하도록 디스패치 합니다.

    const dispatch = useDispatch();
    
      const handleMenuClick = (menuName) => {
        dispatch(setActiveMenu(menuName));
      };

     

    activeMenu가 전체 글 보기와 일치한다면 menu_button 클래스에 추가로 active 클래스를 추가합니다.

    버튼을 클릭하면 handleMenuClick 함수를 호출해서 해당 버튼의 이름을 인자로 전달합니다.

    <button
            className={`menu_button ${activeMenu === '전체 글 보기' ? 'active' : ''}`}
            onClick={() => handleMenuClick('전체 글 보기')}
          >
            전체 글 보기
    </button>
      /*NavBar.css*/
      
      /* 나머지 메뉴 버튼 */
      .menu_button {
        width: 170px;
        height: 70px;
        border: none;
        background-color: transparent;
        color: #2B2B2B;
        font-weight: bold;
        text-align: left;
        margin-left: 60px;
        padding: 10px;
        font-size: 14px;
        cursor: pointer;
        transition: background-color 0.3s, color 0.3s;
      }
      
      /* 클릭 했을 때 */
      .menu_button.active {
        background-color: #8dc693;
        font-weight: bold;
        color: white;
      }

     

     

    NavBar.jsx 전체 코드

    //NavBar.jsx
    
    import React from 'react';
    import { useSelector, useDispatch } from 'react-redux';
    import { selectActiveMenu, setActiveMenu } from '../store/menuSlice';
    import '../styles/NavBar.css';
    
    const NavBar = () => {
      const activeMenu = useSelector(selectActiveMenu);
      const dispatch = useDispatch();
    
      const handleMenuClick = (menuName) => {
        dispatch(setActiveMenu(menuName));
      };
    
      return (
        <div className="navbar">
          <div className="text_menu_big">게시판</div>
          <button
            className={`menu_button ${activeMenu === '전체 글 보기' ? 'active' : ''}`}
            onClick={() => handleMenuClick('전체 글 보기')}
          >
            전체 글 보기
          </button>
          <button
            className={`menu_button ${activeMenu === '자유 게시판' ? 'active' : ''}`}
            onClick={() => handleMenuClick('자유 게시판')}
          >
            자유 게시판
          </button>
          <button
            className={`menu_button ${activeMenu === '인증 게시판' ? 'active' : ''}`}
            onClick={() => handleMenuClick('인증 게시판')}
          >
            인증 게시판
          </button>
          <button
            className={`menu_button ${activeMenu === '환경 정보 게시판' ? 'active' : ''}`}
            onClick={() => handleMenuClick('환경 정보 게시판')}
          >
            환경 정보 게시판
          </button>
          <div className="text_menu_big">마이 페이지</div>
          <button
            className={`menu_button ${activeMenu === '내가 쓴 글' ? 'active' : ''}`}
            onClick={() => handleMenuClick('내가 쓴 글')}
          >
            내가 쓴 글
          </button>
          <button
            className={`menu_button ${activeMenu === '내 정보' ? 'active' : ''}`}
            onClick={() => handleMenuClick('내 정보')}
          >
            내 정보
          </button>
        </div>
      );
    };
    
    export default NavBar;

     

     

     

     

     

    Redux 스토어에 있는 menuSlice.js 파일입니다.

    menu의 상태를 초기화하고 setActiveMenu 액션으로 상태를 변경하고 업데이트하는 Redux Slice를 생성하는 것이 목적입니다. 이렇게 하면 Redux로 전역 상태를 관리할 수 있습니다.

    // menuSlice.js 
    
    import { createSlice } from '@reduxjs/toolkit';
    
    // 초기상태 비워뒀습니다
    const initialState = {
    //   activeMenu: '전체글보기',
    };
    
    //슬라이스 생성
    const menuSlice = createSlice({
      name: 'menu',
      initialState,
      //리듀서 함수 정의
      reducers: {
        setActiveMenu: (state, action) => {
          state.activeMenu = action.payload;
        },
      },
    });
    
    // 액션 생성자를 내보냅니다
    export const { setActiveMenu } = menuSlice.actions;
    // 선택자 함수를 내보냅니다 (현재 활성 메뉴를 선택하는 역할)
    export const selectActiveMenu = (state) => state.menu.activeMenu;
    // 리듀서 함수를 내보냅니다 (상태관리 수행하는 역할)
    export default menuSlice.reducer;

     

     

     

    5. 결과화면

     

     

     

     

     

    참고

    [유튜브] 코딩애플 https://www.youtube.com/watch?v=QZcYz2NrDIs 

    [책] Do it 리액트 모던 웹 개발 with 타입스크립트 

Designed by Tistory.