[크래프톤 정글 3기] 1/1(월) TIL

ClassBinu·2024년 1월 1일
0

크래프톤 정글 3기 TIL

목록 보기
76/120

10:10 입실
리액트 노마더 강의 완강하기
서버 댓글 기능 구현하기

React

props

props는 컴포넌트에 1개의 객체로 전달됨.
props를 {}로 감싸서 넘기면 사용할 때 {props.name}이 아니라 {name}으로 쓸 수 있음. -> 구조 분해 할당

function ExampleComponent({ title, content }) {
  // 여기서 title과 content는 props 객체의 속성입니다.
  return <div>{title} - {content}</div>;
}

// 사용 예:
<ExampleComponent title="제목" content="내용" />

event

컴포넌트에 넣는 onClick은 단지 props이다.
실제 이벤트는 jsx 내에 넣어줘야 함.

import React from 'react';

function MyButton({ onClick }) {
  return (
    <button onClick={onClick}>
      클릭하세요
    </button>
  );
}

function App() {
  const handleClick = () => {
    alert('버튼이 클릭되었습니다!');
  };

  return (
    <div>
      <MyButton onClick={handleClick} />
    </div>
  );
}

export default App;

useEffect()

의존성 배열에 지정된 값이 변경될 때 효과가 실행됨.

import React, { useState, useEffect } from 'react';

function ExampleComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch('https://api.example.com/data');
      const result = await response.json();
      setData(result);
    };

    fetchData();
  }, []); // 의존성 배열이 비어 있으므로 컴포넌트가 마운트될 때만 실행됩니다.

  // ...
}

seEffect Hook 내부에서 반환하는 함수는 "정리(Cleanup)" 함수라고 불리며, 이 함수는 컴포넌트가 파괴되기 전(언마운트 되기 전)에 실행

useEffect(() => {
  // 부수 효과 실행

  return () => {
    // 컴포넌트가 언마운트되거나, 의존성이 변경되어 useEffect가 다시 실행되기 전에 호출될 정리 함수
  };
}, [dependencies]); // 의존성 배열

Next.js

강의보다 Next 튜토리얼이 더 깔끔하다!
리액트 기본 문법만 익히고 Next로 바로 실습해보기!

TS의 interface & type

객체의 모양을 정의하고 클래스와 함께 사용하며 확장 가능성이 있는 경우 interface를 사용합니다.
유니온 타입이나 튜플, 또는 다른 복잡한 타입 조합을 정의할 때 type을 사용합니다.

clsx

JavaScript 또는 TypeScript 프로젝트에서 클래스 이름을 조건부로 결합하거나, 배열 및 객체를 이용해 클래스 이름을 동적으로 만드는 데 사용되는 작고 유용한 유틸리티 라이브러리

layout.tsx

폴더 내 모든 페이지에 layout이 자동으로 중첩됨.

suspend

        <Suspense fallback={<CardsSkeleton />}>
          <CardWrapper />
        </Suspense>

CardWrapper의 로딩(비동기 작업)이 완료될 때까지 fallback의 props로 지정된 컴포넌트를 표시함.

      <Suspense key={query + currentPage} fallback={<InvoicesTableSkeleton />}>
        <Table query={query} currentPage={currentPage} />
      </Suspense>

Suspense 컴포넌트의 key prop은 상태가 변경되었는지 감지하고, 필요한 경우 해당 컴포넌트와 그 자식 컴포넌트들을 재렌더링하기 위한 목적으로 사용

debounce

검색 쿼리를 타자 입력 시 마다 보내는 건 비효율적.
사용자가 입력을 중단한 경우에만 쿼리 보내기

npm i use-debounce
import { useDebouncedCallback } from 'use-debounce';
 
// Inside the Search Component...
const handleSearch = useDebouncedCallback((term) => {
  console.log(`Searching... ${term}`);
 
  const params = new URLSearchParams(searchParams);
  if (term) {
    params.set('query', term);
  } else {
    params.delete('query');
  }
  replace(`${pathname}?${params.toString()}`);
}, 300);

에러 처리

try-catch 로 에러 처리 시 전역 파일 error.tsx 렌더링
단, notFound()가 존재하면 error.tsx보다 우선해서 not-found.tsx로 404 먼저 렌더링

비밀키 생성하는 꿀팁

openssl rand -base64 32

SEO를 위한 메타데이터

루트 layout.ts에 추가하기

import { Metadata } from 'next';
 
export const metadata: Metadata = {
  title: {
    template: '%s | Acme Dashboard',
    default: 'Acme Dashboard',
  },
  description: 'The official Next.js Learn Dashboard built with App Router.',
  metadataBase: new URL('https://next-learn-dashboard.vercel.sh'),
};
 
export default function RootLayout() {
  // ...
}

단, 중첩된 페이지의 메타데이터는 상위 페이지의 메타데이터보다 우선 적용
즉 loot에 title 메타 데이터가 있더라도 하위에 중첩된 페이지나 레이아웃의 메타데이터가 우선 적용됨.

%s는 각 페이지의 메타테이터 값으로 대체됨.

DB 변경

스키마 관리하기 귀찮다고 맨날 MongoDB썼는데 이번에는 postgresQL도전해 봄.
기존 백엔드 DB를 PG로 변경

pg가 postgresQL 노드 드라이버

npm install --save @nestjs/typeorm typeorm pg

typeORM을 쓰면 repository를 따로 만들지 않아도 기본적으로 제공해주는 추상화된 레이어가 있었다. 그럼 mongodb보다 더 간편하잖아?😱

0개의 댓글