税理士目指す人のブログ

筋トレや読書のことをはじめとして、プログラミングその他日常生活における様々なことについて書いていきます。

Output Blog

主に筋トレ・プログラミングについて書きます

React Native入門⑥ WebViewを使ったニュースページ【2020】

スポンサーリンク

React Native入門⑥ WebViewを使ったニュースページ【2020】

React Nativeについて知りたいですか?
前回の記事では、React Nativeを用いてAPIからニュースを取得し表示するページを作成しました。
本記事では、

  • WebViewの使い方
  • 記事をタップしてその記事ページへ飛ぶようにする

といったことを解説します。
アプリ開発に興味のある方必見です。
是非ご覧ください。

WebViewの使い方

WebViewは指定したWebページを表示するコンポーネントです。


公式のドキュメントはこちら。
🚧 WebView · React Native


使い方はこんな感じです。
WebViewは、ExpoのWeb表示だとうまく表示されません。
iOS,またはAndroid表示にするとうまく表示されます。

このコンポーネントを使って、前回作成した記事ページを進化させましょう!
React Native入門⑤ News APIを使ってニュースページを作る【2020】 - 筋トレ大学生によるアウトプット雑記



WebViewを使って、タップで記事ページへ飛ばす

ソースはこちら。

import * as React from 'react';
import {
  FlatList,
  View,
  ScrollView,
  Text,
  ActivityIndicator,
} from 'react-native';
import { WebView } from 'react-native-webview';
import { ListItem, Avatar, Icon } from 'react-native-elements';
import { NavigationContainer} from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

function NewsList({route,navigation}) {
  const [data, setData] = React.useState([]);
  const [load, isLoaded] = React.useState(false);

  function getNews() {
    var url =
      'https://newsapi.org/v2/top-headlines?' +
      'country=jp&' +
      'apiKey=(自分のAPIKey)';
    fetch(url)
      .then(response => response.json())
      .then(result => {
        setData(result.articles);
        isLoaded(true);
      });
  }

  React.useEffect(() => {
    getNews();
  }, []);

  const keyExtractor = (item, index) => index.toString();
  const renderItem = ({ item }) => (
    <ListItem
      onPress={() => {
        navigation.navigate('Web', { url: item.url, title: item.title });
      }}
      title={item.title}
      subtitle={() => <Text>{item.publishedAt.substr(0, 10)}</Text>}
      leftAvatar={() => {
        if (item.urlToImage !== null) {
          return <Avatar size="large" source={{ uri: item.urlToImage }} />;
        } else {
          return (
            <Avatar
              size="large"
              overlayContainerStyle={{ backgroundColor: '#555' }}
              rounded
              icon={{ name: 'file-o', color: '#ffe', type: 'font-awesome' }}
            />
          );
        }
      }}
      bottomDivider
      chevron
    />
  );

  if (!load) {
    return (
      <View style={{ flex: 1, justifyContent: 'center' }}>
        <ActivityIndicator size="large" color="#0000ff" />
      </View>
    );
  }

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <View style={{ width: '100%' }}>
        <FlatList
          keyExtractor={keyExtractor}
          data={data}
          renderItem={renderItem}
        />
      </View>
    </View>
  );
}


function showNews({navigation,route}) {
  React.useEffect(() => {
    navigation.setOptions({
      title:route.params.title
    })
  },[navigation]);
  return (
  <WebView source={{ uri: route.params.url }} />
  )
}

const NewsStack = createStackNavigator();

function stackFirstRoot() {
  return ( 
    <NavigationContainer>
      <NewsStack.Navigator>
                <NewsStack.Screen
                  name="NewsList"
                  component={NewsList}
                  options={{
                    headerStyle:{
                      backgroundColor:"#5bc0de"
                    },
                    headerTintColor:"white",
                    headerTitleStyle:{
                      fontWeight:"bold"
                    },
                    headerTitleAlign:"center"
                  }}
                />
                <NewsStack.Screen name="Web" 
                  component={showNews}
                  options={{
                    headerStyle:{
                      backgroundColor:"#5bc0de"
                    },
                    headerTintColor:"white",
                    headerTitleStyle:{
                      fontWeight:"bold"
                    },
                    headerTitleAlign:"center"
                }}/>
      </NewsStack.Navigator>
    </NavigationContainer>
  )
}
export default stackFirstRoot;


解説していきます。
今回、ページ間遷移はReact Navigationを用いて行います。

まず、ListItemのonPressに対して、navigationを渡します。
この際、パラメータとして、urlとtitleを遷移先のコンポーネントに同時に渡します。
このようにroute.paramsを使うことで、ページ間で値を保持しつつ何かをするということが容易になります。

showNewsコンポーネントでは、受けとったパラメータを用いて
・ヘッダーのタイトルをニュースのタイトルに変更
・WebViewページを指定されたURLを用いて表示
ということを行います。

あとは上記を、スタックナビゲーターでラップするだけですね。
Navigationについては、
React Native入門④ React Navigationを使おう【2020】 - 筋トレ大学生によるアウトプット雑記
にて解説しております。

今回はそこまで難しくありませんね。



実際の表示画面

React Native入門⑥ WebViewを使ったニュースページ【2020】
React Native入門⑥ WebViewを使ったニュースページ【2020】

まとめ

今回は、WebViewを使ったニュースページ制作を行いました。
次回からは、リロード機能などを実装していこうかなと考えています。

スポンサーリンク