깃허브 주소 ▼
개요
목표
로그인 페이지를 만들기 전, `RoutePaths`의 구조와 `NavBarData`를 보다 효율적으로 사용할 수 있게 구조를 바꾸기로 했다. 기존에 사용하던 `navBarData`를 매번 정의해놓고 사용할 수 없기에 이를 보다 효율적으로 작성하고 이용하려고 한다.
RoutePaths와 NavBarData
목표
이전 포스트에서 `RoutePaths`를 만들고 `NavigationBar` 컴포넌트도 Stateless하게 만들어 두었다. 하지만 RoutePaths가 있음에도 불구하고 `NavBarData`라는 데이터를 만들어 이 데이터를 건네주는 식으로 코드를 짰었다. ▼
const navBarData = [
{titleText: "가이드", href: "#guide"},
{titleText: "문의", href: "#faq"},
{titleText: "회원가입/로그인", href: "#login"},
]
그래서 `RoutePaths`의 데이터를 사용하되 독립적이고 전역적으로 존재하는 `navBarData`를 만들고자했다.
트러블 슈팅 1: navBarData에 모든 경로가 다 들어가는건 아니다.
문제
처음에는 `RoutePaths`의 데이터를 전부 받아온 뒤 이를 다른 객체로 변환하여 사용하는 `navBarData`를 구성했다. 그런데 구성하다가 `RoutePaths`가 더 큰 집합이라는 것이 생각났다. 현재는 두 집합의 크기가 거의 동일하지만, 추후에는 `navBarData`에 들어가는 거는 몇 개 되지 않고 `RoutePaths`에 등록된 경로가 훨씬 많아지게 된다.
해결
그래서 이 문제를 해결하고자 RoutePaths에 새로운 값, `isNavItem`을 넣어주었다. `navBarData`는 `RoutePaths`에 있는 값들 중 `isNavItem`이 `true`인 값만 가져가서 새로운 객체로 그 값을 구성하게 된다. 일종의 필터를 걸어주어 문제를 해결했다. ▼
import LoginPage from "../pages/LoginPage";
import MainPage from "../pages/MainPage";
const RoutePaths = [
{ title: "홈", href: "/", page: <MainPage />, isNavItem: false },
{ title: "회원가입/로그인", href: "/login", page: <LoginPage />, isNavItem: true },
];
export default RoutePaths;
트러블 슈팅 2: 초기화되기 전에 메소드와 값을 사용한다.
문제
앞의 미리보는 결론에서 실패했다고 이야기 한 이유가 이 문제 때문이다. `RoutePaths`를 구성한 뒤 `NavBarData.js`라는 별도의 파일에 아래와 같이 값을 넣어두었다. ▼
import RoutePaths from "./RoutePaths";
const NavBarData = RoutePaths
.filter(route => route.isNavItem === true)
.map(route => ({
titleText: route.title,
href: route.href,
}));
export default NavBarData;
하지만 이렇게 작성하면 이런 에러가 나게 된다.
Cannot access '__WEBPACK_DEFAULT_EXPORT__' before initialization
이 에러가 나는 이유는 여러가지인데, 순환 참조를 하거나 이름 그대로 초기화 전에 접근을 했을 때 발생한다. 지금 문제의 경우 순환 참조의 문제 보다는 초기화 전 접근이 문제였던거 같다.
정확한 이유는 아니지만 이렇게 생각한 이유는 const 키워드 때문이다. const는 보통 컴파일 할 때 결정을 해놓는데, 내가 선언한 `RoutePaths`와 `NavBarData`는 모두 const를 달고 있는 상수이다. 컴파일 시간에 둘의 값을 결정해놔야하는데, `NavBarData`에서 사용하고 있는 `RoutePaths`는 모듈로써 제공이 되고 있는데, 이 모듈이 완성되기도 전에 `NavBarData`에서 접근해서 초기화 전 접근 에러가 발생하는 것이었다.
해결
그래서 이를 const로 제공하는 것이 아니라 함수의 형태로 제공하기로 했다. 이렇게 만들어서 값을 주게 되면 초기화 이후에 접근하므로 에러가 발생하지 않는다. ▼
import RoutePaths from "./RoutePaths";
function getNavBarData() {
return RoutePaths
.filter(route => route.isNavItem === true)
.map(route => ({
titleText: route.title,
href: route.href,
}));
}
export default getNavBarData;
import NavigationBar from "../components/NavigationBar";
import getNavBarData from "../constants/NavBarData";
function LoginPage() {
return (
<NavigationBar data={getNavBarData()}></NavigationBar>
);
}
export default LoginPage;
완벽하게 좋다고는 못하는 상황 (+ 장단점)
다만 불필요한 연산을 하게 되는 단점이 있다. 페이지를 이동하고 렌더링을 할 때마다 해당 함수가 실행되기 때문에 성능 면에서는 좋지 못할 수 있다. 그래서 장점과 단점은 아래와 같이 된다.
장점 : `RoutePaths`만 작성해도 `NavBarData`가 자동으로 만들어진다. (하나의 파일만 관리하면 된다.)
단점 : 퍼포먼스가 떨어지는 요인이 될 수 있다. (페이지 이동을 할 때 마다 해당 함수가 실행된다.)
마치며
좀 더 효율적인 구조를 만들고자 하다보니 사소한 부분에서 시간을 많이 소모하게 됐다. 데이터 관리랑 API 호출 등등 아직 할 게 많은데 말이다... 빨리 만들어 보자...!!!
'Develop > React' 카테고리의 다른 글
[React][개발기] 9. 리팩토링과 총 점검 (0) | 2024.07.19 |
---|---|
[React][개발기] 8. Login 모달, 그리고 전체 점검의 필요성 (0) | 2024.07.18 |
[React][개발기] 6. Stateless하기 만들기, 페이지 만들기, 그리고 Map 활용 (0) | 2024.07.17 |
[React][개발기] 5. Component 이어서 만들기와 고민 해결 (0) | 2024.07.16 |
[React][개발기] 4. Styled-Component로 Component 만들기 (0) | 2024.07.16 |