2024.03.19 TIL - next.js 프로젝트에서 src없이 폴더 분리하기, 트러블슈팅(supabase에서 data가 빈배열일때 - RLS policy, api로 불러온 배열data의 type오류)

Innes·2024년 3월 19일
0

TIL(Today I Learned)

목록 보기
92/147
post-thumbnail

Next.js - src없이 폴더 분리하기

📝 프로젝트 생성시 'src폴더를 사용하시겠습니까?'하고 물었을때 No라고 답하면 src폴더 없이 root에 app폴더가 생성된다.
그런데 components, assets등 폴더들을 별도로 관리하고 싶어서 src를 수동으로 생성했더니 internal server error 500이 떴다!

  • 원인 : src를 프로젝트 처음 생성시 만든게 아니라 추후에 수동으로 만들어주려고 하면, 그냥 폴더만 만들어서 app폴더를 옮기는걸로 끝나는게 아니라 추가적인 설정이 필요하다.

  • 해결 : app폴더 안에 private folder를 만드는 방식으로 하면 쉽게 해결된다.

    공식문서 : https://nextjs.org/docs/app/building-your-application/routing/colocation#private-folders

    • 방법 : 폴더명 앞에 언더바 _ 붙여주기!
    • private폴더 안에 있는 폴더 및 파일들은 라우팅과 무관해진다.
      (파일명이 page.tsx 일지라도 라우팅되지 않음)

🏹 트러블슈팅

supabase에서 불러온 data가 빈 배열일때

  • 문제 : 분명 supabase 연결 설정도, key와 url설정도, 데이터를 불러오는 api함수도 전부 이상이 없는데... 정작 data를 불러오면 계속 빈 배열만 들어왔다....!!!

  • 원인 : 코드의 문제가 아니라, table에 대한 접근 권한의 문제였다!
    해당 table에 대한 RLS policy가 하나도 등록되어있지 않은 경우, data를 빈 배열로 반환한다고 안내하고 있다.

    • ⭐️ 아래 페이지처럼 table editor에 접속 - 우측 버튼 중 Add RLS policy를 클릭하여 최소 하나 이상의 policy생성이 필요하다.

    • 아래처럼 Add RLS policy에 커서를 올리면 바로 안내 문구가 뜨는데, 현재 설정된 policy가 없으며 empty array 즉 빈 배열을 return할거라고 이미 말해주고 있다.

  • 해결 : RLS policy를 추가하여 table을 CRUD할 수 있는 접근권한을 설정한다!

    • 1) Add RLS plicy 클릭 - New Policy 클릭

    • 2) Get started quickly 선택 - 별도의 설정 없이 빠르게 new policy를 생성할 수 있다!

    • 3) Enable read access to everyone - 모두가 접근 가능하도록!
      (다른 옵션들은 특정 user_Id를 가진 사람 등 기타 특정 유저에게 권한 부여하는 류의 옵션들이다.)

    • 4) CRUD 모든 사항 대한 접근 권한을 설정해준다. (ALL) - Review 눌러서 권한 설정 코드 preview 후 save policy하면 끝!

참고 : https://github.com/orgs/supabase/discussions/3780

🧡 RLS가 뭘까?

  • Row Level Security의 약자로, table 행에 엑세스할 수 있는 사용자를 제어하는 기능!

api로 불러온 배열data의 type오류

  • 문제 : supabase에서 가져온 data가 배열이었고, 이 data를 사용하려는데 계속 type오류가 떴다.

  • 첫번째 오류 : data는 undefined일 수 있습니다.

    • 시도 : data에 옵셔널 체이닝 추가하기

      const DetailPage = ({ params }: { params: { id: string } }) => {
      const id = +params.id;
      
      const { data, isLoading, isError } = useQuery({
        queryKey: ["post", id],
        queryFn: () => getSinglePost(id),
      });
      
      if (isLoading) {
        return <div>Loading...</div>;
      }
      if (isError) {
        return <div>Error</div>;
      }
      
      // 오류난 부분 - const post = data[0];
      // ⭐️ 옵셔널 체이닝 추가!
      const post = data?.[0];
      
      return (
        //...생략
  • 두번째 오류 : '0' 형식의 식을 'any[] | PostgrestError' 인덱스 형식에 사용할수 없습니다.

    • 원인 : TypeScript가 data가 배열 또는 PostgrestError 타입일 수 있음을 인식하고 있기 때문에 발생
      -> data가 배열이라고 가정하고 배열에 인덱스를 사용하는 경우에는 해당 오류 발생

    • 해결 : ⭐️ Array.isArray() 함수를 사용하여 data가 배열인지 먼저 확인하기!!

      const DetailPage = ({ params }: { params: { id: string } }) => {
      const id = +params.id;
      
      const { data, isLoading, isError } = useQuery({
        queryKey: ["post", id],
        queryFn: () => getSinglePost(id),
      });
      
      if (isLoading) {
        return <div>Loading...</div>;
      }
      // ⭐️⭐️⭐️ Array.isArray()로 data가 배열인지 확인 후, 배열이 아닌 경우에는 error처리 됨
      if (isError || !Array.isArray(data)) {
        return <div>Error</div>;
      }
      
      // ⭐️ 배열이 아닌 경우 error처리 될테니, 여기서 data는 무조건 배열-> 인덱스 사용해도 오류 안남!
      const post = data[0];
      
      return (
profile
무서운 속도로 흡수하는 스폰지 개발자 🧽

0개의 댓글