React Native入門⑦ 画面を引っ張って更新できるようにする【2020】
スポンサーリンク
前:React Native入門⑥ WebViewを使ったニュースページ【2020】 - 筋トレ大学生によるアウトプット雑記
次:React Native入門⑧ AsyncStorageを使って「後で読む」機能を実装する - 筋トレ大学生によるアウトプット雑記
次:React Native入門⑧ AsyncStorageを使って「後で読む」機能を実装する - 筋トレ大学生によるアウトプット雑記
React Nativeについて知りたいですか?
前回の記事では、WebViewを使ったニュースページの作り方を紹介しました。
本記事では、
- RefreshControlの使い方
- Twitterなどのように画面を引っ張ることでニュース内容を更新できる機能を追加
といったことを解説します。
アプリ開発に興味のある方必見です。
是非ご覧ください。
RefreshControlの使い方
RefreshControlコンポーネントはTwitterなどのように、画面を引っ張ると更新する機能です。ニュースなどはそこそこの頻度で更新されますので、新しいニュースなどを読み込ませたいときにこのコンポーネントを利用します。
公式ドキュメントはこちらです。
RefreshControl · React Native
使い方は
scrollviewコンポーネントのrefreshcontrol属性に、返り値としてRefreshControlコンポーネントを指定すればよいです。
実際の使い方は後程記すコードを見ていただくとわかりやすいと思います。
サンプル
このコンポーネントは、Web版では使用できないので注意してください。
更新機能追加
前回に引き続き、ニュースアプリに機能を追加していきましょう。ソースコードはこちら。
import * as React from 'react'; import { FlatList, View, ScrollView, Text, ActivityIndicator, RefreshControl } 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); const [refresh,setRefresh] = 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 /> ); const _onRefresh = React.useCallback(() => { setRefresh(true); getNews(); setRefresh(false); },[refresh]); if (!load) { return ( <View style={{ flex: 1, justifyContent: 'center' }}> <ActivityIndicator size="large" color="#0000ff" /> </View> ); } return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <ScrollView style={{width:"100%"}} refreshControl={ <RefreshControl refreshing={refresh} onRefresh={() => _onRefresh()} /> }> <FlatList keyExtractor={keyExtractor} data={data} renderItem={renderItem} /> </ScrollView> </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;
解説としては、
まずScrollViewの属性に、refreshcontrolを指定します。
refreshcontrolの返り値には、RefreshControlコンポーネントを指定します。
こうすることで、とりあえず「画面を引っ張る」の機能は持たせることができます。
RefreshControlの引数では、
refreshing:更新アイコンの表示
onRefresh:画面を引っ張ったときの動作
という役割があります。
今回、onRefreshには
- refreshingをtrueにする
- 再度getNews()を実行
- refreshingをfalseにする
という中身を持たせています。
こうすることで、更新中にアイコンを表示し、ニュースを取得し終えたらアイコンを非表示にすることができます。
実際の動き
こんな感じになります。
ニュースは短時間に多くは更新されないので今回の例では更新されていませんが、
30分くらいたった後画面を引っ張ると更新されます。
まとめ
ニュースアプリに更新機能を持たせました。かなり便利なコンポーネントですね。