CSR(Client Side Rendering) 오류 (미해결)

LICON·2023년 7월 15일

블로그 프로젝트

짜자잔

제 블로그 모바일 메인 홈페이지 입니다.
저는 JSON 형태로 저장된 포스팅 파일들을 loader를 통해 fetch 함수로 불러와서 메인 화면에 표시했습니다.
loader 함수를 Home 컴포넌트 페이지에 저장하고, index 컴포넌트에서 import 하여 loader를 등록해주었습니다.

//Home.jsx 
import { useState, useEffect } from "react";
import { Link, useLoaderData, useNavigation } from "react-router-dom";
import classes from "./Home.module.css";
import testPostings from "./postings/postings.json";
export function Home() {
  const navigation = useNavigation();
  const [isLoading, setIsLoading] = useState(false);
  const postings = useLoaderData();
  

  return (
    <>
      <div className={classes.grid}>
        <div
          className={
            isLoading //로딩창
              ? classes.loadingBackdrop
              : `${classes.loadingBackdrop} ${classes.hide}`
          }
        ></div>
        <div className={classes.mainBanner}>
          <h1>Welcome to LICON's Blog</h1>
        </div>
        <div className={classes.mainContainer}>
          <div className={classes.heading}>
            <h1>Recent Articles</h1>
            <Link to="/blog" className={classes.btn}>
              View all
            </Link>
          </div>
          <div>
            {postings.map((article, index) => {
              if (index > ) return; // 게시물 5개만 표시
              else
                return (
                  <Link to={`/posting/${article.id}`} key={article.id}>
                    <article className={classes.posting}>
                      <div>
                        <h2>{article.title}</h2>
                        <p>{article.date}</p>
                      </div>
                      <div className={classes.btn}>{article.tag}</div>
                    </article>
                  </Link>
                );
            })}
          </div>
        </div>
      </div>
    </>
  );
}
export async function fetchPostings() {
  const postings2 = await fetch("postings/postings.json");
  const data = await postings2.json();
  return data;
}
//index.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { Home, fetchPostings } from "./routers/Home.jsx";
import About from "./routers/About.jsx";
import Blog from "./routers/Blog";
import Root from "./routers/Root";
import Posting from "./routers/Posting";
const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      {
        index: true,
        element: <Home />,
        loader:fetchPostings
      },
      {
        path: "/blog",
        element: <Blog />,
      },
      {
        path: "/posting/:id",
        element: <Posting />,
        loader: null,
      },
      {
        path: "/about",
        element: <About />,
      },
    ],
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <RouterProvider router={router} />
);

사실 서버가 필요 없으므로 디렉토리에 저장 돼 있는 파일을 import문으로 정적으로 가져오는게 간단하지만, 꿈은 크게 가져야하잖아요? 추후 서비스를 서버에 디플로이 하는 상황을 가정하고 연습하고 싶어서 fetch 함수를 사용했습니다.

Error 등장

Hompage에 포스팅 리스트들을 렌더링 할 때, 로컬 JSON 파일을 loader함수에 등록된 fetch 함수를 통해 불러옵니다.
그런데 PositingDetail 페이지 에서 loader함수가 등록된 Homepage로 이동할 때 에러가 발생했습니다.
에러를 살펴본 결과 증상은 다음과 같았습니다.

증상

  1. deep level 컴포넌트에서 Homepage 컴포넌트로 이동할 때 에러가 발생합니다.( '/events/event/1' -> '/') 하지만 새로고침을 하면 정상적으로 렌더링이 다시 된다.(뭐지?)

  1. same level이나 shallow level component에서 Homepage로 이동할 때는 문제가 없다.('/events' ->'/')

힌트

며칠동안 열심히 이 에러를 해결하려고 공부하고 있고, 다음과 같은 힌트들을 알아냈습니다.

  1. 이 에러는 로컬 디렉토리 파일들을 fetch할 때만 일어난다. fetch 함수 안의 코드 문맥에서 정상적으로 작동되도록하는 url을 넣어주면 에러가 발생하지 않는다.
  2. 이 에러는 CSR(Client Side Rendering)에러다. 새로고침을 할 때는 서버에 request보내고 받기 때문에 문제가 없던 것이었다.

이 버그를 해결하기 위해 stackoverflow에도 질문을 올린 상태고, SPA의 작동원리와 역사들에 대해서 공부를 하고 있습니다.

이렇게 오름차 순이 아닌 내림차 순으로 공부하는게 기억에 더 잘 남는 것 같습니다.

profile
용감한 사나이

0개의 댓글