[React] 블로그 만들기 5 - 페이지네이션 구현
·
Front-End/React
현재 만들어 놓은 list API는 작성된 모든 포스트를 불러오도록 작성되어있다. 만약 포스트 개수가 몇 백 개라면 로딩 속도가 느려질 것이므로 페이지화 하는 것이 좋다. 이를 페이지네이션 (pagination) 한다고 한다. 또, 포스트의 목록을 조회할 때에는 포스트의 내용 중 일부만 보여주고, 클릭시 포스트의 전체 내용을 보여주는 것이 합당하다. 1. 가짜 데이터 생성 우선, 페이지네이션 기능 구현을 위해 가짜 데이터를 생성한다. - src/createFakeData.js import Post from './models/post'; export default function createFakeData() { // 0,1,2, ... 39로 이루어진 배열을 생성한 후 포스트 데이터로 변환 const p..
[React] 블로그 만들기 4 - Request Body 검증
·
Front-End/React
다음은 책 리액트를 다루는 기술을 읽고 공부한 내용을 바탕으로 작성된 글입니다. 이제 포스트 작성시 제목, 내용, 태그를 모두 전달 받도록 만들어보자. 클라이언트가 셋 중 하나의 값이라도 빼먹었을 경우, 400 오류 (Bad Request)가 발생하여야 한다. 지금은 따로 처리하지 않았기 때문에 요청 내용을 비운 상태에서 write API를 실행해도 요청이 성공하여 비어있는 포스트가 등록된다. 객체를 검증하기 위해서는 if 문으로 비교하는 방법도 있지만, 유효성 검사를 도와주는 Joi 라이브러리를 설치하여 사용해보고자 한다. - 터미널 yarn add joi 1. write API 검증 - src/api/posts/posts.ctrl.js import Joi from 'joi'; ... /* POST /..
[React] 블로그 만들기 3 - 요청 검증 (id 검증)
·
Front-End/React
다음은 책 리액트를 다루는 기술을 읽고 공부한 내용을 바탕으로 작성된 글입니다. 클라이언트가 잘못된 id를 전달했다면 400 Bad Request 오류를 띄워주는 것이 올바르다. 현재로서는 올바르지 않은 형식의 id가 전달되면 500 오류가 발생한다. 요청 검증을 통해 400 오류가 뜰 수 있도록 바꿔보자 ! mongoose에서 id 값이 올바른 ObjectId 인지 확인하는 방법은 다음과 같다. import mongoose from 'mongoose'; const { ObjectId } = mongoose.Types; ObjectId.isValid(id); 여기서 id는 검증하고자 하는 id이다. 현재 ObjectId를 검증해야 하는 API는 read, remove, update이다. 이 세 함수에 검..
[React] 블로그 만들기 2 - 데이터 생성, 조회, 삭제, 수정 기능 구현
·
Front-End/React
다음은 책 리액트를 다루는 기술을 읽고 공부한 내용을 바탕으로 작성된 글입니다. 1. 데이터 생성 : 블로그 포스트 작성 - src/api/posts/posts.ctrl.js import Post from '../../models/post'; /* POST /api/posts { title: "제목", body: "내용", tags: ['태그1','태그2'] } */ export const write = async (ctx) => { const {title, body, tags} = ctx.request.body; const post = new Post ({ title, body, tags, }); try{ await post.save(); ctx.body = post; } catch(e) { ctx.t..
[React] 블로그 만들기 1 - MongoDB를 이용하여 스키마, 모델 만들기
·
Front-End/React
다음은 책 리액트를 다루는 기술을 읽고 공부한 내용을 바탕으로 작성된 글입니다. 1. MongoDB MongoDB는 관계형 데이터베이스가 아닌, 문서지향적 NoSQL 데이터베이스이다. 그럼 여기서, 문서란? 문서 ❓ RDBMS의 레코드(record)의 개념. 한 개 이상의 키-값 쌍으로 이루어진다. 다음은 문서의 예이다. - 문서의 예시 { "_id" : ObjectId("509980132123"), "username" : "subbni", "name" : { first : "S.B", last : "Oh" } } 새로운 문서를 만들면 _id라는 고윳값을 자동생성한다. - 문서는 BSON 형태로 저장된다. BSON ❓ JSON 문서를 바이너리로 인코딩한 형태 여러 문서가 들어있는 곳은 컬렉션이라 한다. ..
[React] Koa를 이용한 개발 / 라우터 모듈화 / 컨트롤러 파일 모듈화
·
Front-End/React
다음은 책 리액트를 다루는 기술을 읽고 공부한 내용을 바탕으로 작성된 글입니다. 기존 src/index.js 파일 하나에 모두 작성한 라우터들을 여러 파일에 분리시켜서 작성하여 모듈화 시킨 뒤, 다시 src/index.js 파일에서 불러와 적용하였다. - src/api/index.js const Router = require('koa-router'); const api = new Router(); api.get('/test', (ctx) => { ctx.body = '성공'; }); // 라우터를 내보낸다. module.exports = api; - src/index.js const Koa = require('koa'); const Router = require('koa-router'); const ap..
[React] Koa를 이용한 개발 / Koa, koa-router, nodemon
·
Front-End/React
다음은 책 리액트를 다루는 기술을 읽고 공부한 내용을 바탕으로 작성된 글입니다. const Koa = require('koa'); const app = new Koa(); // ctx : 웹 요청과 응답에 관한 정보가 담김 // next : 현재 처리 중인 미들웨어의 다음 미들웨어를 호출하는 함수 app.use(async (ctx, next) => { console.log(ctx.url); console.log(1); if (ctx.query.authorized !== '1') { ctx.status = 401; //unauthorized return; } // next() 함수는 Promise를 반환한다. await next(); console.log('END'); // next().then(() =>..
[React] Render Props
·
Front-End/React
다음은 책 리액트를 다루는 기술을 읽고 공부한 내용으로 작성된 글입니다. const RenderPropsSample = ({children}) => { return 결과: {children(5)} ; }; export default RenderPropsSample; 만약 위와 같은 컴포넌트가 있다면 추후 사용할 때 다음과 같이 사용할 수 있다. {value=> 2*value}; RenderPropsSample 에게 children으로 함수를 전달하면, 해당 컴포넌트에서는 이 함수에 5를 인자로 넣어서 결과 : 10을 렌더링한다. 이러한 패턴을 Function as a child, 혹은 Render Props라고 한다. 컴포넌트의 children이 있어야 할 자리에 일반 JSX 혹은 문자열이 아닌 함수를 ..
[React] 중첩된 라우트 , Outlet
·
Front-End/React
다음은 책 리액트를 다루는 기술을 읽고 공부한 내용을 바탕으로 작성된 글입니다. function App() { return ( ... ); } 컴포넌트 를 element로 가지는 Route에 을 element로 가지는 컴포넌트가 Children으로 들어가 있다. 다음을 코드를 이어서 보자. const Articles = () => { return ( ... ... ); }; 이라는 컴포넌트를 사용했다. 이는 'react-router-dom'에서 제공하는 컴포넌트로, Route의 children 으로 들어가는 JSX 엘리먼트를 보여주는 역할을 한다. 즉, 이 코드의 경우 의 내용이 Outlet 컴포넌트가 사용된 자리에 중첩되어 보여진다. 즉, Articles 컴포넌트의 맨 윗 부분에 Article 컴포넌트..
[React] URL 파라미터와 쿼리스트링
·
Front-End/React
다음 내용은 책 '리액트를 다루는 기술'을 바탕으로 공부한 내용으로 작성된 글입니다. 페이지 주소를 정의할 때는 가끔 유동적인 값을 사용해야 할 때도 있다. ❕ URL 파라미터 예시 : /profile/velopert - 주소의 경로에 유동적인 값을 넣는 형태. - 주로 id 또는 이름을 사용하여 특정 데이터를 조회할 때 사용. ❕ 쿼리스트링 예시 : /article?page=1&keyword=react - 주소의 '?' 이후에 key=value로 값을 정의, &로 구분하는 형태. - 주로 키워드 검색, 페이지네이션, 정렬 방식 등 데이터 조회에 필요한 옵션을 전달할 때 사용 URL 파라미터 사용 URL 파라미터는 useParams 라는 Hook을 사용하여 객체 형태로 조회 가능하다. 👉 useParam..
[React] 리액트 라우터
·
Front-End/React
다음 내용은 책 '리액트를 다루는 기술'을 바탕으로 작성된 글입니다. ❓ 라우팅이란? 웹 애플리케이션에서 라우팅이라는 개념은 사용자가 요청한 URL에 따라 알맞은 페이지를 보여주는 것을 의미한다. ❓ 싱글 페이지 애플리케이션이란? 하나의 페이지로 이루어진 애플리케이션이라는 의미이다. 싱글 페이지 애플리케이션이란 개념이 생기기 전에는 멀티 페이지 애플리케이션이 사용되었다. 멀티 페이지 애플리케이션에서는 사용자가 다른 페이지로 이동할 때마다 새로운 html을 받아오고, 페이지를 로딩할 때마다 서버에서 CSS, JS, 이미지 파일 등의 리소스를 전달받아 브라우저 화면에 보여 주었다. 반면 싱글 페이지 애플리케이션에서는 우선 웹 애플리케이션을 브라우저에 불러와 실행시킨 후, 사용자와의 인터랙션이 발생하면 필요한..
[React] 컴포넌트 성능 최적화 : 불변성의 중요성
·
Front-End/React
다음 내용은 책 '리액트를 다루는 기술'을 바탕으로 작성된 글입니다. 리액트 컴포넌트에서 상태를 업데이트할 때 불변성을 지키는 것은 매우 중요하다. 기존의 값을 직접 수정하지 않으면서 새로운 값을 만들어 내는 것을 '불변성을 지킨다'고 한다. 다음은 예시이다. const array = [1,2,3,4,5]; const nextArrayBad = array; // 배열을 복사하지 않고 똑같은 배열을 참조함 nextArrayBad[0]= 100; console.log(array === nextArrayBad); // 결과는 true conset nextArrayGood = [...array]; // 배열 내부의 값을 모두 복사 -> 불변성 지켜짐 nextArrayGood[0]=100; console.log(..