오늘은 미완성이나마 Router 만들기 과제를 마쳤다. 그리고 useSyncExternalStore 사용하기 과제를 받았다... 과연 챌린지반인지 점점 과제가 어려워져서 개인과제를 진작 마치지 않았으면 어쩔 뻔 했는지 모르겠다. 오늘은 아티클을 읽으면서 과제를 하는데, 기존에 배운 것 중에도 아티클 내에도 없는 것으로 코드를 완성해야되어서 한참을 고민을 하다가 타임아웃을 받은 참이다.
어쩔 수 없는 일이니만큼 나중에 질문시간을 활용해서 답을 찾을 수 있으면 좋을 것이다.
다만 주요 목표인 Router 만들기 자체는 성공했기 때문에 오늘 이렇게 글을 쓸 수 있게 되었다.
아래가 가장 핵심적인 함수가 담긴 객체를 반환하는 Router 함수이다.
fragment를 인자로 받아서 경로를 변경하는 navigate함수를 이용하여 replace방식으로 페이지를 이동할 수 있다.
export default function createRouter() {
const router = {
// replace로 페이지 이동 / push로 페이지 이동
navigate: (fragment, replace = true) => {
if (replace) {
// 이동할 경로 저장
const href = window.location.href.replace(
window.location.hash,
"#" + fragment
);
// 페이지 이동
window.location.replace(href);
} else {
window.location.hash = fragment;
}
},
};
return router;
}
아티클에서는 이 중 fragment에 인자로 넘어갈 값을 button에 data-navigate로 할당해서 사용했다. 아래는 위 함수를 실행하는 코드이다.
<button data-navigate="/">Home</button>
<button data-navigate="/rara">Rara</button>
// 클릭 이벤트 시 페이지 이동
window.addEventListener("click", (event) => {
// 이동할 경로 지정
if (event.target.matches("[data-navigate")) {
if (event.target.dataset.navigate === "/") {
// html 그리기
container.innerText = "";
pages.home();
} else if (event.target.dataset.navigate === "/rara") {
// html 그리기
container.innerText = "";
pages.rara();
}
// 페이지 이동
router.navigate(event.target.dataset.navigate);
}
});
여기까지가 핵심적인 로직이고,
아래는 router가 경로를 저장하고 경로가 변경됨에 따라 알맞은 html을 그리기까지 하기 위한 함수들이다.
export default function createRouter() {
const routes = []; //경로
const router = {
// 경로 저장
addRoute(fragment, component) {
routes.push({ fragment, component });
return this;
},
// 경로에 따라 html 그리기
start: () => {
const checkRoutes = () => {
// 경로 검사
const currentRoute = routes.find(
(route) => route.fragment === (window.location.hash || "#/")
);
// html 그리기
currentRoute.component() || [];
};
// 페이지 이동 시 html 그리기
window.addEventListener("hashchange", checkRoutes);
checkRoutes();
},
};
return router;
}
그리고 경로로부터 정보를 가져와 html에 그리는 코드를 작성하였는데, 정규식의 구조나 경로를 잘라서 가져오는 과정을 이해할 수 없어서 이 부분만은 실패하고 말았다. 타임아웃을 받아서 일단 여기서 그만두기는 했지만, 언젠가 이러한 구조에서 경로를 가져오는 방법도 알 수 있게 되면 좋겠다.
addRoute(fragment, component) {
// 이 부분에서 name과 song을 추출해서 params에 넣는 것이 문제인데, 정규식을 채 이해하지 못했기 때문에 필요한 부분만 추출해서 저장할 수 없었다.
const params = [];
// 정규표현식과 replace 함수를 이용하여 name과 song 추출
const parsedFragment = fragment
.replace(ROUTE_PARAMETER_REGEXP, (name, song) => {
params.push(name);
params.push(song);
return URL_REGEXP;
})
.replace(/\//g, "\\/");
routes.push({
fragmentRegExp: new RegExp(`^${parsedFragment}$`),
component,
params,
});
return this;
},
'til' 카테고리의 다른 글
useSyncExternalStore사용하기 (1) | 2024.08.28 |
---|---|
뉴스 피드 팀프로젝트 1일 차 @프로젝트 회의 (0) | 2024.08.28 |
reducer 만들기 (0) | 2024.08.26 |
리액트 숙련 5일 차(完) @개인 과제 200% redux-toolkit, memoization, toaster (0) | 2024.08.23 |
리액트 숙련 4일 차 @개인과제 100% (0) | 2024.08.22 |