πŸ—£ λ…Έμ…˜ ν΄λ‘œλ‹ ν”„λ‘œμ νŠΈ 회고

waterglassesΒ·2022λ…„ 4μ›” 22일
1
post-thumbnail

λ…Έμ…˜ ν΄λ‘œλ‹ ν”„λ‘œμ νŠΈμ— λŒ€ν•΄ νšŒκ³ ν•œ λ‚΄μš©μž…λ‹ˆλ‹€. μ˜€νƒ€λ‚˜ 였λ₯˜κ°€ 있으면 λŒ“κΈ€λ‘œ μ•Œλ €μ£Όμ„Έμš©!

πŸ“ν”„λ‘œμ νŠΈ μ†Œκ°œ

λ…Έμ…˜μ„ 바닐라JS만으둜 κ΅¬ν˜„ν•˜λŠ” κ³Όμ œμ˜€μŠ΅λ‹ˆλ‹€. 바닐라JS둜 μ»΄ν¬λ„ŒνŠΈ 뢄리 등을 μƒκ°ν•˜λ©΄μ„œ κ΅¬ν˜„ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

▢️ μ‹€ν–‰ GIF

ν”„λ‘œμ νŠΈ ꡬ쑰 및 μ»΄ν¬λ„ŒνŠΈ

index.html
src
┣ components
┃ ┣ App.js
┃ ┣ DocumentEditor.js
┃ ┣ DocumentList.js
┃ β”— DocumentsPage.js
┣ utils
┃ ┣ api.js
┃ ┣ router.js
┃ β”— storage.js
┣ main.js
β”— style.css

1. 전체적인 μ»΄ν¬λ„ŒνŠΈ κ΅¬μ„±ν•˜κΈ°

μœ„μ™€κ°™μ΄ κ΅¬μ„±ν•˜κΈ° 전에 DocumentListλ₯Ό κ°€μ§€λŠ” νŽ˜μ΄μ§€ ν•˜λ‚˜ DocumentEditorλ₯Ό κ°€μ§€λŠ” νŽ˜μ΄μ§€ ν•˜λ‚˜λ‘œ νŽ˜μ΄μ§€ 2개둜 μž‘μ—…μ„ ν•˜λ‹€κ°€ ν•œ 번 κ°ˆμ•„μ—Žμ—ˆμŠ΅λ‹ˆλ‹€. λΆ„λͺ…νžˆ ν•œ νŽ˜μ΄μ§€μΈλ° κ°•μ˜μ— λ‚˜μ˜¨ λŒ€λ‘œ λ‘κ°œμ˜ νŽ˜μ΄μ§€λ‘œ μž‘μ—…ν•˜λ‹€κ°€ λ³΄λ‹ˆκΉŒ 데이터(state)λ₯Ό κ΄€λ¦¬ν•˜κΈ° λ„ˆλ¬΄ νž˜λ“€μ—ˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ μ‹€μ œλ‘œλ„ λ…Έμ…˜μ΄ ν•œ νŽ˜μ΄μ§€μ— 있기 λ•Œλ¬Έμ— νŽ˜μ΄μ§€λ₯Ό ν•˜λ‚˜λ₯Ό κ΅¬μ„±ν•˜κ³  κ·Έ νŽ˜μ΄μ§€μ—μ„œλ§Œ 데이터λ₯Ό κ΄€λ¦¬ν•˜μžκ³  μƒκ°ν•˜κ³  μ»΄ν¬λ„ŒνŠΈλ₯Ό λ‹€μ‹œ κ΅¬μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

App.js

μ£Όμ†Œμ— 따라 λ‹¬λΌμ§€λŠ” routeκ΄€λ¦¬λ§Œμ„ λ‹΄λ‹Ήν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

DocumentsPage.js

fetch APIλ₯Ό μ‚¬μš©ν•œ λ¬Έμ„œ νŽΈμ§‘κΈ°, λ¬Έμ„œ λ¦¬μŠ€νŠΈλ“€μ— λŒ€ν•œ λͺ¨λ“  데이터듀을 κ΄€λ¦¬ν•©λ‹ˆλ‹€.

DocumentList.js(sidebar)

처음 Root λ¬Έμ„œλ“€μ„ λ Œλ”λ§ ν•˜κ³  ν•˜μœ„ λ¬Έμ„œλ“€μ΄ 있고 없고에 따라 μž¬κ·€μ μœΌλ‘œ λ¬Έμ„œλ₯Ό 보이도둝 ν‘œν˜„ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

DocumentEditor.js

νŽΈμ§‘κΈ°μ— λ‚΄μš©μ„ μž‘μ„±ν–ˆμ„ κ²½μš°μ— 이벀트λ₯Ό ν˜ΈμΆœν•˜μ—¬ μžλ™μœΌλ‘œ μ„œλ²„μ— μ €μž₯ν•˜λ„λ‘ κ΅¬ν˜„ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

2. λ¬Έμ„œ 리슀트(SideBar) κ΅¬ν˜„ 문제

λ¬Έμ„œ 리슀트λ₯Ό λΆˆλŸ¬μ˜€λŠ” κ³Όμ •μ—μ„œ ν”„λ‘œμ νŠΈλ₯Ό 또.. κ°ˆμ•„μ—Žμ—ˆμŠ΅λ‹ˆλ‹€. μ²˜μŒμ— ꡬ쑰λ₯Ό μž‘μ§€ μ•Šκ³  λ¬΄μž‘μ • μ½”λ“œλ₯Ό μž‘μ„±ν•˜λ©΄μ„œ κ΅¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€. κ·Έλž¬λ”λ‹ˆ 리슀트λ₯Ό λΆˆλŸ¬μ˜€λŠ” 것 κΉŒμ§€λŠ” κ΅¬ν˜„ν•˜μ˜€μ–΄λ„ κ·Έ 이후에 μžμ‹ λ¬Έμ„œλ“€ 뢈러였기, λ¬Έμ„œ μΆ”κ°€, ν† κΈ€, μ‚­μ œλ²„νŠΌμ„ κ΅¬ν˜„ν•˜λŠ” κ²ƒμ—μ„œ λͺ¨λ‘ 벽에 λΆ€λ”ͺν˜”μŠ΅λ‹ˆλ‹€.

const renderDocuments = (parentDocumet, currentDocument, depth = 0) => {
	if(currentDocument.length < 1){
    	return;
    }
}

currentDocument.forEach( => {
  //여기에 μžμ‹ λ¬Έμ„œλ“€, ν˜„μž¬ λ¬Έμ„œλ“€μ— λŒ€ν•œ element, class μΆ”κ°€
  // μž¬κ·€λ‘œ 호좜                      
  renderDocuments($document, childDocuments, depth + 1);
})

μœ„μ™€ 같은 ν˜•μ‹μœΌλ‘œ μžμ‹ λ¬Έμ„œλ“€κ³Ό κΈ°λ³Έ λ¬Έμ„œλ“€μ— λŒ€ν•΄ μžμ‹ λ¬Έμ„œλ“€κ³Ό ν•¨κ»˜ μž¬κ·€λ‘œ ν˜ΈμΆœν–ˆμŠ΅λ‹ˆλ‹€. μœ„μ™€ 같은 방식이 λ¬Έμ œκ°€ μžˆλŠ” 것은 μ•„λ‹ˆμ§€λ§Œ λ‹€λ₯Έ κΈ°λŠ₯듀을 μ‰½κ²Œ κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄μ„œλŠ” μžμ‹ λ¬Έμ„œλ“€μ„ λ”°λ‘œ 뢄리해야겠닀고 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ μ•„λž˜μ™€ 같이 μ½”λ“œλ₯Ό λ³€κ²½ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

const renderChildDocumentList = (childDocuments, depth) => {
    if (!childDocuments && childDocuments.length < 1) {
      return;
    }

    return renderDocumentList(childDocuments, depth + 1);
  };

  const renderDocumentList = (documents, depth = 0) => `
    <ul>
      ${documents
        .map((documents) => {        
          return `
			//여기에 κΈ°λ³Έ λ¬Έμ„œ 리슀트 ꡬ쑰 λ„£κΈ°
            ${renderChildDocumentList(documents, depth)}`;
        })
        .join("")}
    </ul>`;

μœ„μ™€ 같이 λ³€κ²½ν•˜μ˜€λ”λ‹ˆ ν•œ λˆˆμ— ν™•μΈν•˜κΈ°λ„ μ’‹κ³  ν† κΈ€, μ‚­μ œ, 좔가에 λŒ€ν•œ μ»΄ν¬λ„ŒνŠΈ κ°„μ˜ 데이터 전달도 νŽΈν•΄μ‘ŒμŠ΅λ‹ˆλ‹€. 이 κ³Όμ •μ—μ„œ 항상 μš”κ΅¬μ‚¬ν•­μ„ λ¨Όμ € λΆ„μ„ν•˜κ³  그것을 ν† λŒ€λ‘œ μ»΄ν¬λ„ŒνŠΈλ₯Ό 섀계 후에 κ°œλ°œμ„ μ‹œμž‘ν•΄μ•Όν•œλ‹€λŠ” 것을 λ‹€μ§ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

😭 λΆ€μ‘±ν–ˆλ˜ λΆ€λΆ„(κ°œμ„  ν•„μš”)

μš°μ„  제일 λˆˆμ— λ„μ—ˆλ˜ 뢀뢄은 제λͺ©μ„ μˆ˜μ •ν•˜μ˜€μ„ λ•Œ λ¬Έμ„œ λ¦¬μŠ€νŠΈμ—μ„œ λ°”λ‘œ λ°˜μ˜λ˜μ§€ μ•Šκ³  λ””λ°”μš΄μŠ€λ‘œ 인해 0.5초 이후에 μˆ˜μ •λ˜λŠ” 뢀뢄이닀. 낙관적 μ—…λ°μ΄νŠΈλ₯Ό λ°°μ› μŒμ—λ„ λΆˆκ΅¬ν•˜κ³  μ–΄λ–€μ‹μœΌλ‘œ stateλ₯Ό λ³€κ²½ν•΄μ•Ό ν•  지 감이 μž‘νžˆμ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. μ²˜μŒμ—λŠ” id값을 μž¬κ·€λ‘œ μ°Ύμ•„μ„œ κ·Έ 값을 λ¦¬μŠ€νŠΈμ—μ„œ 또 μž¬κ·€λ‘œ μ°Ύμ•„ λ°”λ‘œ λ¦¬μŠ€νŠΈμ— λ°˜μ˜ν•˜λŠ” λ°©λ²•μœΌλ‘œ μ§„ν–‰ν•˜μ˜€μŠ΅λ‹ˆλ‹€. μ΄λ ‡κ²Œ μ§„ν–‰ν•˜λ €λ‹€ λ³΄λ‹ˆ λ„ˆλ¬΄ λΉ„νš¨μœ¨μ μΈ κ±°μ„œ κ°™μ•„μ„œ 좔후에 λ‹€μ‹œ κ³ λ―Όν•˜μ—¬ μ μš©ν•  μ˜ˆμ •μž…λ‹ˆλ‹€.

그리고 κ°œλ°œν•˜λ©΄μ„œ 버그가 λ„ˆλ¬΄ 많이 λ°œκ²¬λ˜μ–΄μ„œ 이런 일이 생길 μˆ˜λ„ μžˆλ‹€λŠ” 것을 μΈμ§€ν–ˆμ—ˆμ–΄μ•Ό ν–ˆλŠ”λ° μ—λŸ¬(버그)κ°€ λ°œμƒν•΄μ•Όλ§Œ κ·Έμ œμ„œμ•Ό 잘λͺ» κ΅¬ν˜„ν–ˆλ‹€λŠ” 것을 κΉ¨λ‹«κ³  λ³€κ²½ν•˜λŠ” λ°©μ‹μœΌλ‘œ 반볡되게 κ°œλ°œν•˜μ˜€μŠ΅λ‹ˆλ‹€. μ•„λ¬΄λž˜λ„ μ‚½μ§ˆμ„ ν•˜κ³  λ‚œ 뒀라 λ”μš± 이런 방식이 잘λͺ»λ˜μ—ˆλ‹€λŠ” 것을 더 μ²΄κ°ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

λ§ˆμ§€λ§‰μœΌλ‘œ state값을 λ³€κ²½ν•˜μ§€ μ•Šκ³  계속 리슀트λ₯Ό λΆˆλŸ¬μ™€μ„œ 데이터λ₯Ό μ μš©μ‹œμΌ°λ˜ 점, 그리고 μ‹€μ œ λ…Έμ…˜μ²˜λŸΌ λ¬Έμ„œ λ‚΄μš©μ˜ λ””μžμΈμ„ λ³€κ²½ν•˜λ„λ‘ μ•„μ˜ˆ κ΅¬ν˜„ν•˜μ§€ λͺ»ν–ˆλ˜ 점이 λ„ˆλ¬΄ μ•„μ‰¬μ› μŠ΅λ‹ˆλ‹€. 맀주 μ‹œκ°„μ„ μ‘°κΈˆμ”© λ‚΄μ„œ 배포도 ν•˜κ³  λ¦¬νŒ©ν† λ§μ„ ν•˜λ©° κ°œμ„ ν•΄ λ‚˜κ°ˆ μ˜ˆμ •μž…λ‹ˆλ‹€.

총평

많이 μ•„μ‰¬μ› λ˜ ν”„λ‘œμ νŠΈμ˜€μŠ΅λ‹ˆλ‹€. μ‹œκ°„λ„ λΆ€μ‘±ν•˜μ˜€κ³  μƒνƒœκ΄€λ¦¬, CSS, μ»΄ν¬λ„ŒνŠΈ 뢄리, λ Œλ”λ§ λ“± μ „μ²΄μ μœΌλ‘œ λ‹€μ‹œ λ¦¬νŒ©ν† λ§ν•΄μ•Όκ² λ‹€κ³  μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ 회고λ₯Ό 직접 μž‘μ„±ν•΄λ³΄λ‹ˆ 개발 κ³Όμ •, κ΅¬ν˜„ 방식을 κΈ°λ‘ν•΄λ‘λ©΄μ„œ μž‘μ—…μ„ ν•΄μ•Ό λ‚΄κ°€ μ–΄λ–»κ²Œ κ°œλ°œν•˜κ³  μžˆμ—ˆκ³  λ‹€λ₯Έ 방법은 μ–΄λ–€κ²Œ μžˆμ—ˆλŠ”μ§€, μ–΄λ–€ λ¬Έμ œκ°€ μžˆμ—ˆλŠ”μ§€ 등에 λŒ€ν•œ 생각을 λ°˜λ³΅ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 점도 κΉ¨λ‹¬μ•˜μŠ΅λ‹ˆλ‹€. 이런 것듀을 κΈ°λ‘ν•˜λŠ” μ—°μŠ΅μ΄ ν•„μš”ν•˜λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

λ˜ν•œ λ‚˜λ¦„ 일정 관리도 잘 ν•˜λ©΄μ„œ μ§„ν–‰ν•˜μ˜€λ‹€κ³  μƒκ°ν–ˆμ§€λ§Œ μ˜ˆμƒμΉ˜ λͺ»ν•œ 일은 μ–Έμ œλ“  일어날 수 있고 그에 λŒ€ν•΄μ„œ μ±…μž„μ€ μžμ‹ μ΄ μ Έμ•Ό ν•œλ‹€λŠ” 것을 λ‹€μ‹œκΈˆ 일깨우게 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

ν•˜μ§€λ§Œ 바닐라JS둜 처음 ν•΄λ³Έ ν”„λ‘œμ νŠΈμ˜€μŒμ—λ„ λΆˆκ΅¬ν•˜κ³  ν˜Όμžμ„œ 이정도 κ°œλ°œν•  수 μžˆμ—ˆλ‹€λŠ” 것에 λŒ€ν•΄ λ‚˜λ₯Ό μΉ­μ°¬ν•΄μ£Όκ³  μ‹ΆμŠ΅λ‹ˆλ‹€. 항상 μ„±μž₯이 μ²΄κ°λ˜μ§€ μ•Šμ•˜μ—ˆλŠ”λ° 바닐라JS둜 μ΄μ •λ„κΉŒμ§€ κ΅¬ν˜„ν–ˆλ‹€λŠ” 것에 μΆ©λΆ„νžˆ μ„±μž₯ν•˜κ³  μžˆμ—ˆλ‹€λŠ” 것을 μ΄μ œμ„œμ•Ό κΉ¨λ‹«κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 그리고 λ…Έμ…˜ ν΄λ‘œλ‹ ν”„λ‘œμ νŠΈλ₯Ό ν•˜λ©΄μ„œ νŒ€μ›λ“€κ³Όμ˜ μ†Œν†΅, κ°œλ°œν•˜λ‹€ λ§‰ν˜”μ„ λ•Œ λ™λ£Œλ“€μ΄ μ–Όλ§ˆλ‚˜ 도움이 λ˜λŠ”μ§€ 등에 λŒ€ν•΄μ„œ 큰 κ²½ν—˜μ΄ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

profile
맀 μˆœκ°„ μ„±μž₯ν•˜λŠ” κ°œλ°œμžκ°€ 되렀고 λ…Έλ ₯ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

6개의 λŒ“κΈ€

comment-user-thumbnail
2022λ…„ 4μ›” 22일

리슀트 κ΅¬ν˜„ν•˜μ‹  방식 λ„ˆλ¬΄ λ©‹μ Έμš”! 저도 μž¬κ·€λ‘œν•˜λ©΄μ„œ μ•„...이건 μ•„λ‹Œλ°...싢닀가도 λ§ˆμŒμ΄κΈ‰ν•΄μ„œ κ·Έλƒ₯ 썼닀가, λ‚˜μ€‘κ°€μ„œ 손도 λͺ»λŒ€κ²Œ λ˜λ²„λ Έμ–΄μš”γ… γ…  μ—­μ‹œ 코딩은 greedyν•˜κ²Œ ν•˜λ©΄ μ•ˆλ©λ‹ˆλ‹€...
μˆ˜κ²½λ‹˜ κ³Όμ œν•˜μ‹œλŠλΌ 정말 μˆ˜κ³ λ§ŽμœΌμ…¨μŠ΅λ‹ˆλ‹€!! μ˜ˆμƒμΉ˜ λͺ»ν•œ 상황 μ†μ—μ„œλ„ μ΄λ ‡κ²Œ κ΅¬ν˜„ν•˜μ‹ κ²Œ λ„ˆλ¬΄ λ©‹μ Έμš”~ 이번 ν”„λ‘œμ νŠΈλ₯Ό 발판으둜 더 μ„±μž₯ν•˜λŠ” κ°œλ°œμžκ°€ λ˜μ–΄λ³΄μžκ΅¬μš”~

1개의 λ‹΅κΈ€
comment-user-thumbnail
2022λ…„ 4μ›” 23일

과제 μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€ γ…Žγ…Ž 회고 잘 λ³΄κ³ κ°€μš”!

1개의 λ‹΅κΈ€
comment-user-thumbnail
2022λ…„ 4μ›” 24일

저도 μˆ˜κ²½λ‹˜κ³Ό 같은 고민을 ν–ˆμŠ΅λ‹ˆλ‹€!
"μš°μ„  제일 λˆˆμ— λ„μ—ˆλ˜ 뢀뢄은 제λͺ©μ„ μˆ˜μ •ν•˜μ˜€μ„ λ•Œ λ¬Έμ„œ λ¦¬μŠ€νŠΈμ—μ„œ λ°”λ‘œ λ°˜μ˜λ˜μ§€ μ•Šκ³  λ””λ°”μš΄μŠ€λ‘œ 인해 0.5초 이후에 μˆ˜μ •λ˜λŠ” 뢀뢄이닀. 낙관적 μ—…λ°μ΄νŠΈλ₯Ό λ°°μ› μŒμ—λ„..." 뢀뢄이 정말 κ³΅κ°λ˜λŠ”λ°μš”!
μ €λŠ” 고민을 ν•˜λ‹€κ°€ κ²°κ΅­ TITLE_STATE λΌλŠ” 값을 둜컬 μŠ€ν† λ¦¬μ§€μ— μœ μ§€ν•˜λŠ” λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν•˜μ˜€μŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ λ‘œμ»¬μŠ€ν† λ¦¬μ§€λ₯Ό λ‚¨μš©ν•˜λŠ” 것 κ°™μ•„ λ‹€μŒ ν”„λ‘œμ νŠΈλ•ŒλŠ” μœ μ‚¬ν•œ 상황이 생기면 더 고민을 ν•΄λ³Ό μƒκ°μž…λ‹ˆλ‹€ γ…Žγ…Ž 쒋은 κΈ€ 잘 읽고 κ°‘λ‹ˆλ‹€!! πŸ‘πŸ‘

1개의 λ‹΅κΈ€