News API 서비스를 이용하여 RN에서 News 목록을 작성합니다.

16630 단어 reactnative
일일이 스스로 데이터 만들기의 힘들기 때문에 News API의 API를 이용해 ReactNative로 News 페이지를 만들어 보고 싶다.
이 기사 을 참고로, 단부 접는 곳은 단부 접는다.

완성 이미지





준비



뉴스 API



뉴스 API 사이트 에 가서 등록하여 API를 이용하기 위한 Key를 취득한다.
모처럼이므로 일본어 정보를 요청해 보겠습니다.
https://newsapi.org/v2/top-headlines?country=jp&apiKey=API_KEY

모듈



추가로 설치하는 모듈은 이하의 2개이다.
  • react-native-elements (외형 부품)
  • moment (일반적인 시간을 a hour age로 표시하는 데 사용)
  • npm install --save react-native-elements
    npm install --save moment
    

    뉴스 API 고찰



    응답의 데이터 구조는 다음과 같습니다.
    articles를 얻고, 쓰는 품목을 Loop하는 느낌.
    {
        status: '',
        totalResults: 111,
        articles:[
            {
                source: {
                    id: null,
                    name: ''
                },
                auther: '',
                title: '',
                description: '',
                url: '',
                urlImage: '',
                publishedAt: '2019-09-20T06:19:00Z',
                content: ''
            },
        ]
    }
    

    구현



    전부 App.js에 쓰고 싶은 곳이지만, 기사의 레이아웃만 Article.js로서 외부 파일로 한다.
    /screens/Article.js에 넣습니다.

    App.js



    App.js
    import React from 'react';
    import { StyleSheet, Text, View, FlatList, SafeAreaView } from 'react-native';
    
    import Article from './screens/Article';
    
    export default class App extends React.Component {
    
        state = {
            articles: [],
            refreshing: false,
        }
    
        getNews = async () => {
            this.setState({ refreshing: true });
            const url = "https://newsapi.org/v2/everything?q=bitcoin&from=2019-08-28&sortBy=publishedAt&apiKey={your api key}";
            try {
                const result = await fetch(url);
                const json = await result.json();
                // console.log(json);
                this.setState({
                    articles: json.articles,
                    refreshing: false
                });
            } catch (e) {
                this.setState({ refreshing: false });
                console.log(e);
            }
        }
    
        componentDidMount = () => { 
            this.getNews();
        }
    
        render() {
            // console.log(this.state.articles);
            return (
                <SafeAreaView style={{ flex: 1 }}>
                    <FlatList
                        data={this.state.articles}
                        keyExtractor={item => item.url}
                        renderItem={({ item }) => <Article article={item} />}
                        onRefresh={() => this.getNews()}
                        refreshing={this.state.refreshing}
                    />
                </SafeAreaView>
            );
        }
    }
    
    

    Article.js



    Article
    import React from 'react';
    import { View, Linking, TouchableHighlight } from 'react-native';
    import { Text, Button, Card, Divider } from 'react-native-elements';
    import moment from 'moment';
    
    export default class Article extends React.Component {
        render() {
            const { description, publishedAt, source, urlToImage, url } = this.props.article;
            const time = moment(publishedAt || moment.now()).fromNow();
            // const time = publishedAt;
            const defaultImage = "https://wallpaper.wiki/wp-content/uploads/2017/04/wallpaper.wiki-Images-HD-Diamond-Pattern-PIC-WPB009691.jpg";
            return (
                <TouchableHighlight
                    useForeground
                    onPress={() => Linking.openURL(url)}
                >
                    <Card
                        image={{ uri: urlToImage || defaultImage }}
                    >
                        <Text style={{ marginBottom: 10 }}>{description || 'Read more...'}</Text>
                        <Divider style={{ backgroundColor: "#dfe6e9" }} />
                        <View style={{ flexDirection: "row", justifyContent: 'space-around' }}>
                            <Text style={{ margin: 5, fontSize: 10 }}>{source.name.toUpperCase()}</Text>
                            <Text style={{ margin: 5, fontSize: 10 }}>{time}</Text>
                        </View>
                    </Card>
                </TouchableHighlight>
            );
        }
    }
    

    좋은 웹페이지 즐겨찾기