목록전체 글 (293)
가수면
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..
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와 유사하게 요청을 처리하는 방법을 추가했..
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()의 좌표값을 직접 넣게 되면 드래그가 되지 않는다. 드래그가 되려면 요소의 좌표가 마우스의 움직임에 따라 계산되어야 하는데 요소의 현재 좌표값을 넣어봐야 아무 소용도 없을 것이다. 그렇기에 해야할 것..
객체는 생성될 때 내부 프로퍼티([[Prototype]])를 가지게 되는데 이 내부 프로퍼티가 다른 객체를 참조하는 경우 참조 대상을 '프로토타입(prototype)'이라 부른다. 프로토타입은 객체의 상위(부모) 역할을 하는 객체이며, 객체는 프로토타입의 속성과 메서드를 상속받아 사용할 수 있다. 그렇게 객체의 [[Prototype]] 연결을 따라 상위 프로토타입을 찾아가는 것을 '프로토타입 체인'이라고 한다. 프로토타입은 부모 객체이지만, 모든 객체가 동일한 프로토타입을 참조한다고 보긴 어렵다. 생성될 때 자신만의 프로토타입을 가지게 된다는 것이 맞을 것이다. 두 코드를 잘 비교해보자. class A { method() { console.log('A 메서드 호출'); } } class B {} B.pr..
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)
내부 파일 사용할 때 서버에서만 사용할 수 있음. 클라이언트 컴포넌트에서 사용 불가 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..
클라이언트 컴포넌트, 서버 컴포넌트 선택 기준 Next 13 이상의 버전에서는 기본적으로 컴포넌트가 서버 컴포넌트와 클라이언트 컴포넌트로 구분되는데, 그렇다고 서버 컴포넌트=SSR, 클라이언트 컴포넌트=CSR개념은 아니다. 서버 컴포넌트 SSR의 경우 동적 컨텐츠를 다루는데, 서버 컴포넌트의 경우 동적 상호작용하는 로직들을 전부 클라이언트 컴포넌트에 위임함으로써 클라이언트에 전송되는 자바스크립트의 양을 최소화하는 데 초점을 맞춘 컴포넌트다. SSR의 특정 역할을 클라이언트 컴포넌트에 덜어주어 최적화시킨 형태다. 클라이언트 컴포넌트 마치 SSR처럼 서버에서 렌더링 된 HTML을 생성한 뒤 클라이언트에서 수화 과정을 거치게 된다. 이후 CSR처럼 클라이언트 사이드에서 동적 컨텐츠들을 처리한다. SSR + C..
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..
그래프 (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..
이진 탐색 트리와 이진 힙 비교 힙은 각 노드의 값이 자식 노드보다 크거나 같음(Max Heap의 경우) 이진 탐색 트리는 왼쪽 자식 노드의 값이 가장 작고, 그 다음 부모 노드, 그 다음 오른쪽 자식 노드 값이 가장 큼 힙은 이진 탐색 트리의 조건인 자식 노드에서 작은 값은 왼쪽, 큰 값은 오른쪽이라는 조건은 없음 힙의 왼쪽 및 오른쪽 자식 노드의 값은 오른쪽이 클 수도 있고, 왼쪽이 클 수도 있음 최대 이진 힙 왼쪽 오른쪽 구분 없이 부모 노드가 자식 노드보다 항상 큰 트리 구조 왼쪽 자식 노드 인덱스 => 2n+1 오른쪽 자식 노드 인덱스 => 2n + 2 부모 인덱스 => Math.floor((n - 1) / 2) insert 매소드 class MaxBinaryHeap { constructor()..
너비 우선 탐색 vs 깊이 우선 탐색 시간 복잡도는 같음. 다만, 공간 복잡도에서 효율 차이가 존재함. 깊이가 깊은 트리의 경우 =>너비 우선 탐색 사용 (너비가 넓으면 큐에 노드가 많이 추가됨) 너비가 넓은 트리의 경우 => 깊이 우선 탐색 사용 깊이 우선 탐색 종류 // 10 // 6 15 // 3 8 20 전위 순회 - [10, 6, 3, 8, 15, 20]을 반환하므로 10을 루트로 삼아서 다시 만들 때 좋음(데이터 이전, 복사 등) 후위 순회 - [3, 8, 6, 20, 15, 10] 중위 순회 - 반환되는 값이 오름차순을 이룸 [3, 6, 8, 10, 15, 20] 이진 트리를 예제로 함 너비 우선 탐색 class Node { constructor(value) { this.value = val..
이진 탐색 트리와 이진 힙 비교 힙은 각 노드의 값이 자식 노드보다 크거나 같음(Max Heap의 경우) 이진 탐색 트리는 왼쪽 자식 노드의 값이 가장 작고, 그 다음 부모 노드, 그 다음 오른쪽 자식 노드 값이 가장 큼 힙은 이진 탐색 트리의 조건인 자식 노드에서 작은 값은 왼쪽, 큰 값은 오른쪽이라는 조건은 없음 힙의 왼쪽 및 오른쪽 자식 노드의 값은 오른쪽이 클 수도 있고, 왼쪽이 클 수도 있음 insert 매소드 class Node { constructor(value) { this.value = value; this.left = null; this.right = null; } } class BinarySearchTree { constructor() { this.root = null; } inser..
직접 구현하면 배열의 인덱스도 덜고 배열에 딸려오는 매서드들도 덜어낼 수 있다. 수 만 개의 요소를 저장하는데 push, pop과 같은 기능만 사용할 거라면 배열을 사용할 이유가 없음 스택 pop의 경우 시간복잡도가 O(N)이므로 shift와 unshift를 사용하는 것이 효율적이다. shift와 unshift의 기능을 수행하지만 편의상 push와 pop으로 만듦. class Node { constructor(val) { this.val = val; this.next = null; } } class Stack { constructor() { this.head = null; this.tail = null; this.length = 0; } push(val) { let newNode = new Node(va..
기본적으로는 단일 연결 리스트와 동일하지만 prev가 있어 탐색에 더 용이하 메모리가 더 많이 먹음 노드 자바스크립트 ver. class Node { constructor(val) { this.val = val; this.prev = null; this.next = null; } } 파이썬 ver. class Node: def __init__(self, data): self.data = data self.prev = None self.next = None push 매소드 만들기 자바스크립트 ver. class DoublyLinkedList { constructor() { this.head = null; this.tail = null; this.length = 0; } push(val) { let newN..