https://github.com/tutv/rn-hacker-news
Build Hacker News app with React Native
https://github.com/tutv/rn-hacker-news
fetch fetch-api hacker-news react-native reactjs
Last synced: 27 days ago
JSON representation
Build Hacker News app with React Native
- Host: GitHub
- URL: https://github.com/tutv/rn-hacker-news
- Owner: tutv
- Created: 2018-07-27T17:04:58.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2018-08-02T04:20:28.000Z (almost 8 years ago)
- Last Synced: 2025-08-11T13:33:58.423Z (10 months ago)
- Topics: fetch, fetch-api, hacker-news, react-native, reactjs
- Language: JavaScript
- Homepage:
- Size: 1.1 MB
- Stars: 1
- Watchers: 1
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Sử dụng Fetch API xây dựng ứng dụng Hacker News
## Mục tiêu
- Biết cách sử dụng `Fetch API` để tạo HTTP request.
- Biết thay đổi các tham số trong `Fetch API` để tạo các request khác nhau.
- Biết cách gọi request trong `life cycle` của React một cách đúng đắn.
## Mô tả
- Tạo 1 ứng dụng với chức năng hiển thị danh sách tin tức từ [Hacker News](https://github.com/HackerNews/API)
## Hướng dẫn
### Bước 1
- Tạo project với `create-react-native-app`.
### Bước 2
- Tạo 1 component `HomePage` trong đó có chứa 2 component `Header` và `TopNews`.
### Bước 3
- Trong `TopNews` component chúng ta sẽ gọi đến API tại hook `componentDidMount`:
```javascript
import React, {Component} from 'react'
import {View, Text, ScrollView, RefreshControl, StyleSheet} from 'react-native'
import NewsItem from "./NewsItem"
class TopNews extends Component {
state = {
news: [],
error: '',
loading: false
}
_mounted = false
componentDidMount() {
this._mounted = true
this._fetchListNews()
}
componentWillUnmount() {
this._mounted = false
}
_fetchListNews = () => {
if (this.state.loading) return
this.setState({loading: true})
fetch('https://hacker-news.firebaseio.com/v0/topstories.json')
.then(response => response.json())
.then(result => {
if (!this._mounted) return
this.setState({
loading: false,
news: Array.isArray(result) ? result : [],
error: ''
})
})
.catch(error => {
if (!this._mounted) return
const message = error.message || 'Fetch list news failed'
this.setState({
error: message,
loading: false
})
})
}
_handleRefresh = () => {
this._fetchListNews()
}
render() {
const {news, error, loading} = this.state
return (
}>
{
!!error ? {error}
: news.map((id, index) => {
return
})
}
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
width: '100%',
backgroundColor: '#f6f6ef',
paddingLeft: 10,
paddingTop: 10,
paddingBottom: 10
}
})
export default TopNews
```
Note: Ở trong component này có sử dụng `RefreshControl` để cho phép người dùng refesh lại danh sách news.
### Bước 4
- Do API lấy danh sách news chỉ lấy ra được `ID` của news nên trong từng `NewsItem` chúng ta sẽ gọi tiếp API để lấy ra nội dung của news đó.
- Trong component `NewsItem` chúng ta sẽ gọi API tại hook `componentDidMount` và gọi lại API khi `ID` của nó thay đổi bằng cách kiểm tra trong hook `componentDidUpdate`.
```javascript
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {View, Text, StyleSheet} from 'react-native'
import moment from 'moment'
class NewsItem extends Component {
state = {
news: {},
loading: false
}
componentDidMount() {
const {index} = this.state
setTimeout(() => {
this._fetchDetail()
}, index * 1000 || 0)
}
componentDidUpdate(prevProps, prevState) {
if (prevProps.id !== this.props.id) {
this._fetchDetail()
}
}
_fetchDetail = () => {
const {id} = this.props
this.setState({
loading: true
})
fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`)
.then(response => response.json())
.then(result => {
this.setState({
news: result ? result : {},
loading: false
})
})
.catch(error => {
console.error('Fetch error', error)
this.setState({loading: false})
})
}
render() {
const {index} = this.props
const {news, loading} = this.state
const score = news.score || 0;
const pointText = score > 1 ? 'points' : 'point'
const timeAgo = moment(news.time * 1000).fromNow()
return (
{index + 1}.
{
loading ? 'Loading...' : news.title
}
{
!!news && Object.keys(news).length &&
{news.score || 0} {pointText} {timeAgo}
}
)
}
}
NewsItem.propTypes = {
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
index: PropTypes.number.isRequired,
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
marginBottom: 10,
},
left: {
marginRight: 10
},
right: {},
index: {
color: '#828282',
fontSize: 14,
minWidth: 15,
textAlign: 'right'
},
title: {
color: '#000',
fontSize: 14,
marginRight: 20,
flex: 1,
flexWrap: 'wrap'
},
meta: {
color: '#828282',
fontSize: 12
}
})
export default NewsItem
```
### Bước 5
- Chạy chương trình và quan sát kết quả.
## Mã nguồn
Tham khảo tại: https://github.com/tutv/rn-hacker-news
## Ảnh demo
