목록분류 전체보기 (297)
가수면
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/cNPQWH/btsuZSFmUw9/5fRKWnXX0CK1PAplkBjrD1/img.png)
기본 동작 use client를 사용한 클라이언트 컴포넌트라도 초기 페이지 로드 시에는 서버에서 생성된 html파일을 받아온다. 실제로 개발자 도구에서 받아온 페이지의 요소들을 확인해보면 클라이언트 컴포넌트 안에 있는 요소들도 다 포함이 되어있다. 초기 페이지 로딩 성능을 최적화하려는 Next의 최적화 전략이다. 문제는 이러한 SSR + CSR를 혼합한 방식으로 인해 클라이언트 컴포넌트에 몇 가지 제약이 생긴다는 것이다. 1. 초기 렌더링 시 어떤 요소를 보여줄 건지 결정하는 로직들이 사용 불가능하다. 서버 사이드 렌더링된 컨텐츠와 클라이언트 사이드에서 렌더링하려는 컨텐츠가 다르면 안 된다. 예를 들어 쿠키, 리액트 쿼리의 isLoading 등을 이용해 초기 뷰를 분기 처리하려는 경우 수화 과정에서 받아..
npm i swr 전역 설정 'use client'; import { SWRConfig } from 'swr'; type Props = { children: React.ReactNode; }; export default function SWRConfigContext({ children }: Props) { return ( fetch(url).then((res) => res.json()), }} > {children} ); } 해당 컴포넌트를 provider로 사용하면 아래처럼 간단하게 api요청 함수를 사용할 수 있음 const { data, isLoading, error } = useSWR('/api/me'); mutate의 경우 mutate만 해줄 경우 해당 api 데이터로 요청이 가지만, 아래처럼 ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/eqRgYF/btsj044R538/gVkzHEtWJLjcgBKpY0Zuv1/img.png)
이걸 내가 다시 만질 날이 올 줄이야... 기본 세팅 npm i mongodb import { MongoClient, ServerApiVersion } from "mongodb"; const uri = process.env.MOGO_DB_URI ?? ""; const client = new MongoClient(uri, { serverApi: { version: ServerApiVersion.v1,// MongoDB 서버 API 버전 strict: true,// 엄격 모드 deprecationErrors: true,// 오래된 버전이면 에러 뱉을 건지 }, }); 데이터 베이스에 접근 export async function GET() { const mongo = await client.connect();..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/b7hP1x/btsjXUGY1KQ/1XEksxqAwHjKRsslAWALyk/img.png)
'개체 리터럴은 알려진 속성만 지정할 수 있으며 '{ name?: string | null | undefined; email?: string | null | undefined; image?: string | null | undefined; }' 형식에 'username'이(가) 없습니다.' 기존 라이브러리 없는 속성을 지정할 경우 이러한 타입 오류가 발생한다. 이 경우 라이브러리에서 선언된 타입에 속성을 추가해주면 된다. 라이브러리에 선언 된 타입 확인하기 DefaultSession에 usename이라는 타입을 추가해주면 된다. 추가하기 // src\types\next-auth.d.ts import NextAuth, { DefaultSession } from 'next-auth'; declare modu..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/9H0M4/btsjmCf3ako/qCElfjGNaBYWjD77VELkG1/img.png)
Parallel Routes 동일한 레이아웃에서 하나 이상의 페이지를 동시에 렌더링시킬 수 있다. 핵심 컨텐츠들을 여러 개로 나누어 관리하거나 분기처리할 때 유용하다. export default function Layout(props: { children: React.ReactNode analytics: React.ReactNode team: React.ReactNode }) { return ( {props.children} {props.team} {props.analytics} ) } 컨벤션은 '@폴더명'을 사용하며, 해당 폴더 안의 layiut, loading 등은 각각 독립적으로 작동한다. 또, '@폴더명'은 경로에 영향을 주지 않기 때문에 파일 경로 /@team/members의 경우 /member..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bn4MVm/btsjkhDCTDS/0e0tBPaytKlcmQVcjQuRnK/img.png)
npm install next-auth 배포 시 주의할 점 환경 변수인 NEXTAUTH_URL 추가할 필요 없음 사용법 next 이전 버전 /pages/api/auth/[...nextauth].ts import NextAuth from "next-auth" export default NextAuth({ ... }) next 최신 버전 /app/api/auth/[...nextauth]/route.ts import NextAuth from "next-auth" const handler = NextAuth({ ... }) export { handler as GET, handler as POST } 공식문서에 따르면 Next 13.2 이상의 버전에 대응하기 위해 REST와 유사하게 요청을 처리하는 방법을 추가했..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/duYxJ2/btsjlYQPV3Z/jchC6kM8p161sus49dd81K/img.png)
https://www.sanity.io/docs/overview-introduction Welcome to Sanity's Documentation Here you'll find ways to get started, understand core concepts, and explore a variety of resources to help you get the most from Sanity. We also recommend joining our Slack community for help along the way. Sanity Studio was recently released in a new majo www.sanity.io headless CMS Content Lake안에 있는 데이터베이스를 사용하는데..
npm install nodemailer npm i --save-dev @types/node let transporter = nodemailer.createTransport({ host: "받는 사람 메일", port: 587, secure: false, // true일 경우 port 465로 수정 auth: { user: process.env.AUTH_USER,// 보내는 사람 아이디 pass: process.env.AUTH_PASS,// 보내는 사람 메일 비번 }, }); export async function sendEmail({ subject, from, message }: EmailData) { const mailData = { from, to: process.env.AUTH_USER, subj..
https://github.com/remarkjs/react-markdown GitHub - remarkjs/react-markdown: Markdown component for React Markdown component for React. Contribute to remarkjs/react-markdown development by creating an account on GitHub. github.com npm install react-markdown 사용법 적용할 컨텐츠를 감싸거나 import React from 'react' import ReactMarkdown from 'react-markdown' import ReactDom from 'react-dom' ReactDom.render(# He..
드래그 앤 드롭에 필요한 준비물은 다음과 같다. 1. 드래그 시킬 요소의 ref값 2, 뷰 포트를 기준으로 한 마우스 좌표 값 (드래그를 발생시킬 핵심 재료) 3. 드래그 시킬 요소를 기준으로 한 마우스 좌표 값 (요소 내 커서 좌표) 로직의 작동 원리는 다음과 같다. onMouseMove 이벤트가 발생할 때 목표 요소의 current.style.transform의 translate를 getBoundingClientRect() 좌표값으로 설정해주면 된다. 그러나 이때 getBoundingClientRect()의 좌표값을 직접 넣게 되면 드래그가 되지 않는다. 드래그가 되려면 요소의 좌표가 마우스의 움직임에 따라 계산되어야 하는데 요소의 현재 좌표값을 넣어봐야 아무 소용도 없을 것이다. 그렇기에 해야할 것..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bsd03y/btsi3WkVwG6/6lr11hTYvlpxHVFGnm5y50/img.png)
객체는 생성될 때 내부 프로퍼티([[Prototype]])를 가지게 되는데 이 내부 프로퍼티가 다른 객체를 참조하는 경우 참조 대상을 '프로토타입(prototype)'이라 부른다. 프로토타입은 객체의 상위(부모) 역할을 하는 객체이며, 객체는 프로토타입의 속성과 메서드를 상속받아 사용할 수 있다. 그렇게 객체의 [[Prototype]] 연결을 따라 상위 프로토타입을 찾아가는 것을 '프로토타입 체인'이라고 한다. 프로토타입은 부모 객체이지만, 모든 객체가 동일한 프로토타입을 참조한다고 보긴 어렵다. 생성될 때 자신만의 프로토타입을 가지게 된다는 것이 맞을 것이다. 두 코드를 잘 비교해보자. class A { method() { console.log('A 메서드 호출'); } } class B {} B.pr..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/ceikax/btsiX1mxu4q/rqrm5VTXcRh2j7rm0c8xf1/img.png)
https://tailwindcss.com/docs/installation Installation - Tailwind CSS The simplest and fastest way to get up and running with Tailwind CSS from scratch is with the Tailwind CLI tool. tailwindcss.com next에서 src 경로 사용할 경우 /** @type {import('tailwindcss').Config} */ module.exports = { content: [ './app/**/*.{js,ts,jsx,tsx,mdx}', // Note the addition of the `app` directory. './pages/**/*.{js,ts,jsx,..
라우팅 관련 useNavigae => useRoute의 매소드를 이용함 useParams => usePathname url이름 확인할 때 => usePathname().startsWith(url)
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/rxtxg/btskeMI4dwi/bfK8AZkL7o7X0wv9h5MZZ1/img.png)
내부 파일 사용할 때 서버에서만 사용할 수 있음. 클라이언트 컴포넌트에서 사용 불가 import path from "path"; import { promises as fs } from "fs"; export type Food = { id: string; name: string; price: number; }; /** */ export async function getFoods(): Promise { const filePath = path.join(process.cwd(), "data", "food.json"); // data/food.json 경로 순서대로 스트링 넣어주면 됨 const data = await fs.readFile(filePath, "utf-8"); return JSON.parse(dat..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/Zylcp/btsiOiPMChP/udUv7YW5Yxaz3L9zZF8CV0/img.png)
클라이언트 컴포넌트, 서버 컴포넌트 선택 기준 Next 13 이상의 버전에서는 기본적으로 컴포넌트가 서버 컴포넌트와 클라이언트 컴포넌트로 구분되는데, 그렇다고 서버 컴포넌트=SSR, 클라이언트 컴포넌트=CSR개념은 아니다. 서버 컴포넌트 SSR의 경우 동적 컨텐츠를 다루는데, 서버 컴포넌트의 경우 동적 상호작용하는 로직들을 전부 클라이언트 컴포넌트에 위임함으로써 클라이언트에 전송되는 자바스크립트의 양을 최소화하는 데 초점을 맞춘 컴포넌트다. SSR의 특정 역할을 클라이언트 컴포넌트에 덜어주어 최적화시킨 형태다. 클라이언트 컴포넌트 마치 SSR처럼 서버에서 렌더링 된 HTML을 생성한 뒤 클라이언트에서 수화 과정을 거치게 된다. 이후 CSR처럼 클라이언트 사이드에서 동적 컨텐츠들을 처리한다. SSR + C..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/cFUqvx/btr8zliEdW8/UmyXAZv8WdVb4SfKe8OMkK/img.png)
npm run dev보다 npm run build 후 npm start하면 더 빠름 pakage.json에 있는 스크립트의 dev를 "next dev --turbo"로 수정해 터보팩을 적용하면 프로젝트 규모가 클 수록 더 빠른 업데이트를 체감할 수 있다. (현재 개발 환경에서만 사용 가능) 설정 tsconfig.json에 compilerOptions의 target을 ES5에서 ES6로 수정해서 설정해주면 최적화 측면에서 좀 더 좋음 라우팅 기본 방식 app안에 폴더를 만들고 page 파일 생성 Route Groups 라우팅에 간섭하는 기능은 없음. 그러나 상위 세그먼트의 레이아웃 등에 더해 추가적으로 그룹 내에서 독립적으로 설정할 수 있는 기능이 있음 다이나믹 라우팅 상대 경로가 어떻게 되었든 해당 컴포..
너비 우선 탐색 2개의 큐를 이용 A큐 - 방문한 노드들을 쌓는다. 쌓일 때 연결된 노드들을 B큐에 추가한다. B큐 - 초깃값을 설정한 뒤 큐에 값이 없을 때까지 실행한다. 맨 앞의 노드를 A로 내보낸 뒤 해당 노드와 연결된 노드를 큐에 추가한다. 이때 A에 중복된 노드가 있다면 A에 저장하지 않는다 자바스크립트 ver. class Graph { constructor() { this.adjacencyList = {}; } addVertex(vertex) { if (!this.adjacencyList[vertex]) this.adjacencyList[vertex] = []; } addEdge(vertex1, vertex2) { this.adjacencyList[vertex1].push(vertex2); t..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/sQFgC/btshBm0IHvY/Pmc5tRkri1XmYIrWbhrkKk/img.png)
그래프 (Graph) 관련 용어 노드 (Node): 위치를 말함, 정점(Vertex)라고도 함 간선 (Edge): 위치 간의 관계를 표시한 선으로 노드를 연결한 선이라고 보면 됨 (link 또는 branch 라고도 함) 인접 정점 (Adjacent Vertex) : 간선으로 직접 연결된 정점(또는 노드) 참고 용어 정점의 차수 (Degree): 무방향 그래프에서 하나의 정점에 인접한 정점의 수 진입 차수 (In-Degree): 방향 그래프에서 외부에서 오는 간선의 수 진출 차수 (Out-Degree): 방향 그래프에서 외부로 향하는 간선의 수 경로 길이 (Path Length): 경로를 구성하기 위해 사용된 간선의 수 단순 경로 (Simple Path): 처음 정점과 끝 정점을 제외하고 중복된 정점이 없..
해시 함수 조건 1. 빨라야 함 루프를 최대한 줄여야 함 조건 2. 특정값'만' 뱉으면 안 됨 (충돌 조건임) 예) return 0 조건 3. 같은 값에 대해선 같은 값을 뱉어야 함 Math.floor같은 것을 사용하면 안 됨 소수를 곱해주면 충돌 확률이 낮아짐 function hash(key, arrayLen) { let total = 0; let PRIME_NUMBER = 31; for (let i = 0; i < Math.min(key.length, 100); i++) { let char = key[i]; let value = char.charCodeAt(0) total = (total * PRIME_NUMBER + value) % arrayLen; } return total; } 해시 테이블 ge..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bmMOvV/btsz2ZSw3lV/pQo9WfoWoc9uuD6mwwIXj1/img.png)
이진 탐색 트리와 이진 힙 비교 힙은 각 노드의 값이 자식 노드보다 크거나 같음(Max Heap의 경우) 이진 탐색 트리는 왼쪽 자식 노드의 값이 가장 작고, 그 다음 부모 노드, 그 다음 오른쪽 자식 노드 값이 가장 큼 힙은 이진 탐색 트리의 조건인 자식 노드에서 작은 값은 왼쪽, 큰 값은 오른쪽이라는 조건은 없음 힙의 왼쪽 및 오른쪽 자식 노드의 값은 오른쪽이 클 수도 있고, 왼쪽이 클 수도 있음 최대 이진 힙 왼쪽 오른쪽 구분 없이 부모 노드가 자식 노드보다 항상 큰 트리 구조 왼쪽 자식 노드 인덱스 => 2n+1 오른쪽 자식 노드 인덱스 => 2n + 2 부모 인덱스 => Math.floor((n - 1) / 2) insert 매소드 class MaxBinaryHeap { constructor()..