목차
1. 자동 저장 편집기 만들기
자동저장 편집기는 별도의 저장 버튼없이 서버와 자동으로 싱크되는 편집기 이다. url에 따른 라우팅 처리 필요
1-1.페이지 및 컴포넌트 구조
<App>
- 기능
PostPage, PostEditPage 생성
router(url path) 에 따라 PostPage와 PostEditPage를 렌더링 하는 역할
커스텀 이벤트를 통해 라우트 처리 (6강)
- state
posts : []
- 컴포넌트
- <PostPage>
- <PostEditPage>
<PostPage>
기본 경로로 들어왔을 때의 컴포넌트
- 기능
post를 불러와 렌더링 (
PostList
)post 클릭 시, 해당 post를 수정하는 페이지로 이동 (
onPostClick(id)
)하단 부 post를 생성할 수 있는 페이지 이동 링크 존재 (
addNewPost
)- 컴포넌트
<PostList onPostClick={} >
<button onclick = { addNewPost } />
<PostEditPage>
post를 생성하고, 수정할 수 있는 페이지
- 기능
- id가 new 일 경우 빈 값을 가지고, 새로운 post를 생성하는 Editor id의 값이 있을 경우, 해당 id의 post를 불러와서 렌더링 함
- autosave
- 텍스트 내용 입력 시, debounce처리 되어, 1초후 로컬스토리지에 저장되도록 함
- 처음 불러온 DB값의 데이터와 비교 후, 로컬스토리지 시간이 더 최근이라면, alert창 띄워서 선택하도록 함
- new로 들어왔는데, 1글자라도 입력이 발생하여 isCreated 상태로 변경되었다면, 현재 url 패스도 변경되어야 함 (
history.replaceState이용
)
- state
{ postId: ‘new’, post: { title, content }}
- 컴포넌트
<Editor post >
<Editor>
title과 content 내용을 입력할 수 있으며, 입력한 값은 1초 후에 localStorage에 저장됨
- 어려웠던 점
문제
title, textarea 값 변경 시 setState를 사용하는데, 이 때 render 함수가 호출되며, 화면이 새로 그려져 연속적으로 값을 입력할 수 없었다.해결
initialize 플래그를 통해, 최초에만 innterHTML로 마크업을 렌더링 하고, 이후에는 렌더링에 반영하지 않는다. (반영하지 않아도, 직접 입력하는 값들을 실시간으로 화면에서 확인할 수 있기 때문에) 즉 setState는 작동하여 state값은 변하되, render는 처음만 작동한다.문제2
editor의 state를 어디서 보관하는 것이 옳은지 (editor내부 vs editPage)해결2
1-2 API 구조
편집 가능 글 불러오기
GET
https://kdt.roto.codes/posts
특정 게시글 불러오기
GET
https://kdt.roto.codes/posts/{id}
게시글 저장하기
POST
https://kdt.roto.codes/posts
게시글 수정하기
POST
https://kdt.roto.codes/posts/{id}
1-3 작업순서
PostPage 하단 컴포넌트 부터 만들어 위로 올리기
(
request → postList → postPage → App
)- posts를 불러와 화면 렌더링 확인 작업
- 더미데이터를 통한 렌더링 테스트
<PostList />
더미데이터 렌더링 테스트
- request.js 생성
- 기본적인 API 동신을 위한 모듈 생성
API test
- <PostList> 컴포넌트 생성
- posts받아와서, html요소에 맞게 렌더링
- onPostClick 이벤트함수 아직 미작성
실제 API를 통해 받아온 post 렌더링
- <PostPage> 컴포넌트
- posts 받아와서 PostList로 넘겨주기
- post추가 버튼 생성
- <App> 컴포넌트
- 기본 state 정의(posts)
- api요청을 통해 posts 받아와 업데이트
Editor 컴포넌트 작업
feat Editor 컴포넌트
style, title, content(textarea)
editor input과 textarea의 event 처리
init flag를 통한 리렌더 방지하고, onEditing() 함수로 변경사항을 state에 반영하기
(로컬스토리지 저장, 초기값 꺼내서 사용하기) - 디바운스 처리하기
feat. postId의 path값과 EditPage연동
생성버튼 클릭 시, new Editor 이동
기존 리스트 클릭시, 해당 포스트 받아와 editor 페이지 렌더링
feat 로컬스토리지 저장 및 연동
디바운스 처리하여, 데이터 로컬스토리지에 저장하기
새로고침 시 현재 시각 비교하여, DB데이터와 로컬스토리지 데이터 중 선택
EditPage 작업
id에 따라 해당하는 타이틀 컨텐트 불러오도록 작성
App 컴포넌트 작업
url 규칙 정하기
- post/{id} , post/new
route()
메소드 생성- pathName에 따라서 페이지 렌더링
route를 onClickPost 가 아니라 custumEvent 정의하여, route이동이 발생했을 경우에 해당 id를 받아와서 라우트 이동처리를 하도록함
onClick 이벤트는 달아주는데, custom-route이벤트 발생하도록 함
- Editor
- editor는 2가지 방법으로 생성가능
- style
- size 조절 (600px * 600px)
- event 버블링을 통한 contents 수정
- input / textarea 의 name을 동적으로 받아 값의 변화를 반영하도록 핸들링
- 로컬스토리지의 현재 시각 담아 저장하기
- 디바운스 처리하기
- 매 타이핑 마다, 로컬스토리지에 저장이 되는 것이 아니라, 1초동안 반응이 없을 경우에만 로컬스토리지에 저장이 되도록
textarea
VS contenteditable
속성 중 선택하여 구현 가능