基本功練習: Hacker News! — Part 4: Recursion

基本功練習: Hacker News! — Part 4: Recursion

基本功練習: 使用純 JS + Redux 把 Hacker News 做出來。

前情提要

view

我們個別頁面已經寫好啦,現在該來處理醜醜的留言顯示了!

留言顯示

開始前,我們先來觀察一下 comments。

注意到了嗎?他是一層又一層的!(nested object)

我們在寫 comments 這頁時,要把這個特點考慮進去。

先繼續依照 React 的 Component 邏輯,把每個 comments 拆到他們各自的 Component 裡面吧:

item.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 以上省略

export default async function Item() {
  const story = await getStory();  
  const hasComments = story.comments.length > 0;
  
  view.innerHTML = `
  <div>
    ${Story(story)}
  </div>
  <hr/>
  ${hasComments ? story.comments.map(comment => Comment(comment)).join('') : '沒留言耶'}
  `  
}

// 以下省略

Comment.js:

1
2
3
4
5
6
7
8
9
10
11
export default function Comment(comment) {
    console.log(comment); 
    return `
    <div class="nested-comments-0">
      <p class="comment-header">
        ${comment.user} | ${comment.time_ago}
      </p>
      ${comment.content}
    </div>
  `   
}

我們來看看畫面:

view

留言出來了沒錯,可是有看到每一筆下面還有一層 comments 嗎?

這就是我們之前觀察到的 nested comments,我們需要處理他!

我們需要讓 Comment 一直產生畫面直到 comments 裡面沒有任何 comments 為止。

所以,先寫個判斷是否有 nested comments 吧。

1
const hasNestedComments = comment.comments.length > 0;

如果有 nested comments 的話,那我們加個判斷讓他產生畫面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export default function Comment(comment) {
  const hasNestedComments = comment.comments.length > 0;

  return `
    <div class="nested-comments-0">
      <p class="comment-header">
        ${comment.user} | ${comment.time_ago}
      </p>
      ${comment.content}
      ${hasNestedComments ? comment.comments.map(comment => Comment(comment)).join("") : ""}
    </div>
  `   
}

1
${hasNestedComments ? comment.comments.map(comment => Comment(comment)).join("") : ""}

這一行的意思是,如果 hasNestedComments = true 的話,那 Comment function 會一直自己呼叫自己直到 hasNestedComments = false。

也就是所謂的 recursion function

再修改一下 css,讓每一層巢狀 comments 都會被往右邊推。

1
<div class="nested-comments-${comment.level}">

我們的留言區就變成這樣了~

view

快寫完了!現在我們只剩下最後一個功能,我的最愛頁面。

而這一塊,我想用 Redux pattern。

這樣就可以讓用戶在新聞列表直接將喜歡的新聞加進我的最愛頁面,也可以在將新聞從我的最愛移除。

最重要的是,在我們切換頁面時,資料不會流失!