基本功練習: Hacker News! — Part 2: API
基本功練習: 使用純 JS + Redux 把 Hacker News 做出來。
前情提要
我們的 Hacker News 框架已經出來呢,現在就是把資料丟進去。
這裡我們會用 API 去抓資料,配合對應的 routes 把他顯示出來。
API
先把東西弄出來再慢慢 format。
要用的 API 是這個:https://node-hnapi.herokuapp.com
接著要用 async + await 寫我們的 stories。
stories.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import view from '../utils/view.js';
export default async function Stories(path) {
const stories = await getStories(path);
const hasStories = stories.length > 0;
view.innerHTML = `<div>
${hasStories ? stories.map(story => JSON.stringify(story)) : '沒有 stories 耶'}
</div>`;
}
async function getStories(path) {
const isHomeRoute = path === '/';
const isNewRoute = path === '/new';
if (isHomeRoute) {
path = '/news';
} else if (isNewRoute) {
path = '/newest';
}
const response = await fetch(`https://node-hnapi.herokuapp.com${path}`);
const stories = await response.json();
return stories;
}
我們的畫面就會變成這個鬼樣子:
嗯,很醜。
不過,沒關係,我們來美化它。
資料一大坨進來,依照我們的 React 原理,現在是應該把他拆成可以重複使用的原件了,我們的 Component!
以此類推,我們要建立一個新的 js 檔來裝每條新聞。
首先我們先把 API data 丟進創建好的 Story Component。
1
2
3
4
5
6
7
8
9
10
11
12
13
import Story from '../components/Story.js'; // import 進來
import view from '../utils/view.js';
export default async function Stories(path) {
const stories = await getStories(path);
const hasStories = stories.length > 0;
view.innerHTML = `<div>
${hasStories ? stories.map((story, i) => Story({ ...story, index: i + 1 })).join('') : '沒新聞耶'}
</div>`;
}
// 以下省略
我稍微解釋一下為什麼這邊會這樣寫:
1
stories.map((story, i) => Story({ ...story, index: i + 1 })).join('')
首先,stories 會吐出有一堆 object 的 array,所以需要用到 .join(‘’) 才不會每一筆資料都有 , 在後面。
然後,我們想要在每條新聞前顯現順序數字,可是 array 是從 0 開始,所以我們在 map 裡面要用 i + 1 來設立 index。
因為 Story Component 只接受一個 parameter,所以我們用 object 的方式,配合 spread operator 去寫他。
最後,只要把 Story Component,照著 Hacker News 的模式 把畫面刻出來,就 OK 了~
story.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
export default function Story(story) {
return `
<div class="story">
<div>
<span class="gray">${story.index}</span>
<span class="upvote">▲</span>
<a href="${story.url}">${story.title}</a>
<span>(${story.domain})</span>
</div>
<div>
<div class="gray">
${story.points} points by ${story.user} ${story.time_ago}
|
<a href="#/item?id=${story.id}">
${story.comments_count} comments
</a>
|
<span class="favorite">
♥
Add To Favorites
</span>
</div>
</div>
</div>
`;
}
我們再來看看畫面:
嗯,好多了。
下一篇,我們接著要寫每條新聞按進去後,可以看到留言的頁面~