-
[메인프로젝트] 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 타입스크립트
'IT > 회고' 카테고리의 다른 글
[메인프로젝트] Button component 구현 (0) 2023.08.30 [부트캠프] 코드스테이츠 FE45 Section3 회고 (0) 2023.07.06 [부트캠프] 코드스테이츠 FE45 Section2 회고 (0) 2023.06.08