LoginSignup
7
6

More than 3 years have passed since last update.

【React Native】 axios を使用し、一覧表示する。

Posted at

axios

axiosとは、ブラウザやnode.js上で動くPromiseベースのHTTPクライアントです。
DBの情報をバックエンドのApiを叩いて取得する際にオーソドックスな方法になります。

完成形

スクリーンショット 2020-07-08 10.33.24.png

現在勉強をかねて、Instagramを模倣してアプリケーションを作成しています。
こちらの表示もバックエンドからaxiosを使用しデータを取得しています。

使用技術

  • expo
  • ReactNative
  • JSX

ファイルディレクトリー

---components
      |
      |---- Listitem.js (一つ一つの投稿をコンポーネント化)

--screens
      |
      |---- HomeScreen.js (ホーム画面)

ソースコード

HomeScreen.js


import React, { useState, useEffect } from 'react';
import { StyleSheet, View, FlatList } from 'react-native';
import ListItem from '../components/ListItem';
import axios from 'axios';

//* 今回はDBにFirebaseを使用しています。
const URL = 'https://firestore.googleapis.com/v1/projects/?????/databases/(default)/documents/????';

//* navigationは遷移させるときに必要になるものです。
export default  HomeScreen = ({ navigation }) => {

  //* Hooks の導入
  const [posts, setPosts] = useState([]); 
  // * useEffect 導入 コンポーネントのマウント時に発火させるアクションを宣言
  useEffect(() => { 
    fetchPosts();
  }, []);

  // * Axios getMethods
  const fetchPosts = async () => {
    try {
      const response = await axios.get(URL);
      const arrayPost = response.data.documents;
      setPosts(arrayPost);
      // console.log(arrayPost);  dataの確認
    } catch (error) {
      console.error(error);
    }
  }

  return (
    <View style={ styles.container }>
      <FlatList
        data={ posts }
        renderItem={({ item }) => (
          <ListItem
            item = {item.fields}
            userName={ item.fields.user_name.stringValue }
            userImage={ item.fields.user_image.stringValue }
            imageUrl={ item.fields.urlToImage.stringValue }
            content={ item.fields.content.stringValue }
            onPress={() => navigation.navigate('Article', { article: item })}
          />
        )}
      />
    </View>
  );
}

Listitem.js

import React from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';

const ListItem = ({userImage, userName, imageUrl, content, onPress}) => {

  return (
    <View style={ styles.postWrapper } onPress={ onPress }>
      <View style={ styles.topBox }>
        <View style={ styles.topBoxLeft }>
          <View style={ styles.userImage }>
            <Image
            style={ styles.userImage }
            source={{ uri: userImage }}
            />
          </View>
          <Text style={ styles.userName }>{ userName }</Text>
        </View>
      </View>
      <View style={ styles.middleBox }>
        <Image
        style={ styles.middleBox }
        source={{ uri: imageUrl }}
        />
      </View>
      <View style={ styles.bottomBox }>
        <View style={ styles.bottomBoxArea }>
          <View style={ styles.bottomLeftArea }>
            <Icon name="heart-o" size={30} style={styles.icon1}/>
            <Icon name="comment-o" size={30} style={styles.icon2}/>
            {/* 詳細画面に遷移する */}
            <TouchableOpacity onPress={ onPress }>
              <Icon name="send-o" size={30} style={styles.icon3}/>
            </TouchableOpacity>
          </View>
          <View style={ styles.bottomCenterArea }></View>
          <View style={ styles.bottomRightArea }>
            <TouchableOpacity onPress={() => {//action}}>
              <Icon name="bookmark-o" size={30} style={styles.icon4}/>
            </TouchableOpacity>
          </View>
        </View>
        <View style={ styles.bottomTopArea }>
          <Text>{ content }</Text>
        </View>
      </View>
    </View>
  )
}

ここでは、FontAwesome等を使用していますが、一旦そちらの説明は割愛致します。

HomeScreen.js 説明

ここで使用しているものは、
1) useState
2) useEffect
3) axios
4) FlatList

1) useState

useStateはFunctionコンポーネントで記述する際に、状態の変化を受け取るために使用します。
現在推奨としてfunctionコンポーネントでの書き方のようなので、こちらでは使用しています。

https://ja.reactjs.org/docs/hooks-effect.html


import React, { useState, useEffect } from 'react';

const [posts, setPosts] = useState([]); //からの配列に値を入るように設定

2) useEffect

useEffectは、component が mount されたタイミングで api を呼ぶために使用しています。
ページが開かれた際に真っ先に読んで欲しいapiのため、こちらを使用します。


import React, { useState, useEffect } from 'react';

  const [posts, setPosts] = useState([]); 
  // * useEffect 導入 コンポーネントのマウント時に発火させるアクションを宣言
  useEffect(() => { 
    fetchPosts();
  }, []);

https://ja.reactjs.org/docs/hooks-effect.html

3) axios

import axios from 'axios';


  // * Axios getMethods
  const fetchPosts = async () => {
    try {
      const response = await axios.get(URL);
      const arrayPost = response.data.documents;
      setPosts(arrayPost);
      // console.log(arrayPost);  dataの確認
    } catch (error) {
      console.error(error);
    }
  }

今回は、async function を使用しています。
非同期関数 — AsyncFunction オブジェクトである関数を定義します。非同期関数はイベントループを介して他のコードとは別に実行され、結果として暗黙の Promise を返します。ただし、非同期関数を使用したコードの構文および構造は、通常の同期関数と似たものになります。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function

こちらのtry以降でバックエンドから配列で[] 値を取得しています。
そしてそれをuseStateで作成した


  const [posts, setPosts] = useState([]); 

第二引数のsetPost関数の中に格納します。
それにより、
第一引数であるpostsのなかにdataが格納されます。

4) FlatList


  return (
    <View style={ styles.container }>
      <FlatList
        data={ posts } //先ほどのdataを指定
        renderItem={({ item }) => (
          <ListItem
            item = {item.fields}
            // こちらはFirebase特有に少し独特です...
            userName={ item.fields.user_name.stringValue }
            userImage={ item.fields.user_image.stringValue }
            imageUrl={ item.fields.urlToImage.stringValue }
            content={ item.fields.content.stringValue }
            onPress={() => navigation.navigate('Article', { article: item })}
          />
        )}
      />
    </View>
  );

https://reactnative.dev/docs/flatlist

上記がHomeScreen.js でのAxiosの使用方法になります。
それをListitemコンポーネントに値を継承させ少しコードをすっきりさせています。

React Native初心者になるため、何か間違い等あればご指摘お願いします!!!!

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6