検索バーをフックとフラットリストを使用してネイティブの反応を追加


一般的なユースケースは、ネイティブの反応で携帯アプリを開発するときにデータを表示するリストの形式です.
つの一般的な方法が作成リストにネイティブな反応に存在します.ScrollView and FlatList . フレームワークのAPIからのこれらのコンポーネントの各々は、その強さを持ちます.
このチュートリアルでは、私たちは別の小道具をFlatList データを取得し、データを表示し、検索バーを追加します.

必要条件


このチュートリアルに従うには、JavaScript/ES 6に慣れていることを確認し、ローカルのdev環境で次の要件を満たしてください.

  • Node.js バージョン>=12.x.x インストール
  • NPMや糸などの1つのパッケージマネージャにアクセスできます

  • expo-cli インストールされたバージョンまたはNPXを使用する
  • 次のチュートリアルの例はExpo SDK38 .

    始める


    新しいEXPOベースのプロジェクトを作成するには、ターミナルウィンドウを開き、次のコマンドを実行します.
    必ずインストールするlodash.filter プロジェクトディレクトリが生成されたあと.リストの機能から検索を追加するときに、後でパッケージを使用してデータをフィルタリングします.
    npx expo init [Project Name]
    
    # choose a template when prompted
    # this example is using the 'blank' template
    
    # after the project directory has been generated
    
    cd [Project Name]
    
    # install dependency
    yarn add lodash.filter
    
    新しいプロジェクトが作成され、その中に移動したらyarn start . あなたはシミュレータや実際のデバイスを使用するかどうか、次の結果を得るつもりです.

    フラットリストコンポーネントの使用


    ネイティブの反応FlatList 全体的なパフォーマンスを劣化させることなく大量のデータから成るスクロールリストを作成する効率的な方法です.これは、画面上に表示される項目のセットだけをレンダリングするため、データの大規模な配列に最適です.データのリストをスクロールするとき、内部状態は保存されません-コンポーネントをマウントした直後にすべてのデータをレンダリングします.これは、ScrollViewのすべてのデータがデバイスのメモリにマウントされ、大量のデータがレンダリングされているときにパフォーマンスが低下する可能性があることを意味します.
    データの配列をFlatList データの一覧を表示できる方法です.これがどのように機能するか見てみましょう.例えば、オープンApp.js 関数コンポーネントの前に、次のデータ列を追加します.
    const data = [
      { id: '1', title: 'First item' },
      { id: '2', title: 'Second item' },
      { id: '3', title: 'Third item' },
      { id: '4', title: 'Fourth item' }
    ];
    
    次に、インポートFlatListApp.js ファイル.
    import { StyleSheet, Text, View, FlatList } from 'react-native';
    
    The FlatList データの一覧を表示するために必要な三つのプライマリ小道具を使用します.
  • data : リストを作成するために使用するデータの配列.配列は複数のオブジェクトから構成されます.
  • keyExtractor : はFlatList 一意の識別子またはid 配列の個々の要素に対して.
  • renderItem : データの配列から個々の要素を受け取り、UI上でレンダリングする関数.
  • そして、App このリストを返すコンポーネントdata .
    export default function App() {
      return (
        <View style={styles.container}>
          <Text style={styles.text}>Basic FlatList Example</Text>
          <FlatList
            data={data}
            keyExtractor={item => item.id}
            renderItem={({ item }) => (
              <View style={styles.listItem}>
                <Text style={styles.listItemText}>{item.title}</Text>
              </View>
            )}
          />
        </View>
      );
    }
    
    以下を加えてくださいstyles オブジェクト.
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#f8f8f8',
        alignItems: 'center'
      },
      text: {
        fontSize: 20,
        color: '#101010',
        marginTop: 60,
        fontWeight: '700'
      },
      listItem: {
        marginTop: 10,
        padding: 20,
        alignItems: 'center',
        backgroundColor: '#fff',
        width: '100%'
      },
      listItemText: {
        fontSize: 18
      }
    });
    
    今、シミュレータに戻って、あなたは、すべてのオブジェクトを参照してくださいdata 配列は、リストの形式で表示されます.使用FlatList 組織化されたデータを表示するために最小限の労力を要する.

    フラットリストのAPIからデータを取得する


    フラットリストは、モバイルアプリケーションがデータを取得している方法について気にしない.前のセクションでは、データの配列をモックする方法を学びました.この節では、リモートAPIリソースからデータを取得し、同じパターンに従ってデータを表示します.
    side note :リモートAPIリソースの場合は、Random User Placeholder API .
    このセクションで使用するすべての必要なコンポーネントをインポートして起動します.次のインポート文を更新します.
    import React, { useState, useEffect } from 'react';
    import {
      StyleSheet,
      Text,
      View,
      FlatList,
      ActivityIndicator,
      Image
    } from 'react-native';
    
    次に、APIエンドポイントのURLを定義し、データを定数として取得します.
    const API_ENDPOINT = `https://randomuser.me/api/?seed=1&page=1&results=20``;
    
    APIエンドポイントへのHTTPリクエストは、最初の20の結果を取得します.
    内部の3つの状態変数を定義しますApp 反応フックを使用しているコンポーネントuseState . The isLoading 状態変数は、false デフォルトでは.その目的は、データがAPIエンドポイントからフェッチされているときにローディング指標を表示することです.
    The data 変数はデフォルトで空の配列を持ちます.この状態変数を使用するFlatList がデータのリストを表示するように設定されます.
    最後の状態変数error , のデフォルト値null . データを取得する際にエラーが発生した場合のみ更新されます.
    export default function App() {
      const [isLoading, setIsLoading] = useState(false);
      const [data, setData] = useState([]);
      const [error, setError] = useState(null);
    
      // ...
    }
    
    次に、反応フックを使用するuseEffectfetch JavaScriptからAPIを取得しますAPI_ENDPOINT . 以下のようにします.App コンポーネント.
    The loading 変数がtrue 一度useEffect インスタンス化する.この変数のboolean値はfalse データの取得が完了した場合やエラーが発生した場合のいずれか.The setData 以下は更新data データの配列を持つ変数.
    export default function App() {
      // state variables defined
    
      useEffect(() => {
        setIsLoading(true);
    
        fetch(API_ENDPOINT)
          .then(response => response.json())
          .then(results => {
            setData(results);
            setIsLoading(false);
          })
          .catch(err => {
            setIsLoading(false);
            setError(err);
          });
      }, []);
      // ...
    }
    
    次に2を加えるif 条件は、それぞれ2つの異なるシナリオのJSXを返します.まず、データが取り出されているとき、ローディングインジケータが示される.第2に、エラーがあるとき、エラーメッセージが表示されます.
    export default function App() {
      // state variables defined
    
      // fetch data using useEffect
    
      if (isLoading) {
        return (
          <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <ActivityIndicator size="large" color="#5500dc" />
          </View>
        );
      }
    
      if (error) {
        return (
          <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text style={{ fontSize: 18}}>
              Error fetching data... Check your network connection!
            </Text>
          </View>
        );
      }
      // ...
    }
    
    そして、FlatList ユーザーのアバターとAPIエンドポイントから取得したユーザーの名前を表示します.
    export default function App() {
      // ...
    
      return (
        <View style={styles.container}>
          <Text style={styles.text}>Favorite Contacts</Text>
          <FlatList
            data={data}
            keyExtractor={item => item.first}
            renderItem={({ item }) => (
              <View style={styles.listItem}>
                <Image
                  source={{ uri: item.picture.thumbnail }}
                  style={styles.coverImage}
                />
                <View style={styles.metaInfo}>
                  <Text style={styles.title}>{`${item.name.first} ${
                    item.name.last
                  }`}</Text>
                </View>
              </View>
            )}
          />
        </View>
      );
    }
    
    更新することを忘れないでくださいstyles オブジェクトも同様です.
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#f8f8f8',
        alignItems: 'center'
      },
      text: {
        fontSize: 20,
        color: '#101010',
        marginTop: 60,
        fontWeight: '700'
      },
      listItem: {
        marginTop: 10,
        paddingVertical: 20,
        paddingHorizontal: 20,
        backgroundColor: '#fff',
        flexDirection: 'row'
      },
      coverImage: {
        width: 100,
        height: 100,
        borderRadius: 8
      },
      metaInfo: {
        marginLeft: 10
      },
      title: {
        fontSize: 18,
        width: 200,
        padding: 10
      }
    });
    
    以下を使用して表示される連絡先の一覧を次に示しますFlatList 我々はこのステップの後に取得するつもりです.

    データが取り出されているとき、ローディング指標はここにあります.

    以下のシナリオは、アプリケーションがデータを取得することができないです.

    検索バーを追加


    この節では、現在の検索バーを作成しましょうFlatList . 支柱という支柱ListHeaderComponent 検索バーを表示するには.
    編集を始める前にApp このステップで必要なインポート文を追加します.からreact-native , インポートを追加TextInput . また、インポートlodash.filter .
    import {
      StyleSheet,
      Text,
      View,
      FlatList,
      ActivityIndicator,
      Image,
      TextInput
    } from 'react-native';
    import filter from 'lodash.filter';
    
    にプロップを加えるFlatList 下記の通り.
    <FlatList
      ListHeaderComponent={renderHeader}
      // ... rest of the props remain same
    />
    
    次にrenderHeader 以下のJSXを返す関数です.
    export default function App() {
      //...
      function renderHeader() {
        return (
          <View
            style={{
              backgroundColor: '#fff',
              padding: 10,
              marginVertical: 10,
              borderRadius: 20
            }}
          >
            <TextInput
              autoCapitalize="none"
              autoCorrect={false}
              clearButtonMode="always"
              value={query}
              onChangeText={queryText => handleSearch(queryText)}
              placeholder="Search"
              style={{ backgroundColor: '#fff', paddingHorizontal: 20 }}
            />
          </View>
        );
      }
    // … render JSX below
    }
    
    このステップの後のシミュレータの出力です.

    次に、さらに2つの状態変数を追加します.最初にquery は、データのリストを検索するユーザーが提供する任意の入力を追跡する予定です.空の文字列のデフォルト値があります.次に、データをフィルタリングするために使用するAPIからデータを保持する別の変数を追加します.
    const [query, setQuery] = useState('');
    const [fullData, setFullData] = useState([]);
    
    副作用の更新useEffect 人口を占めるfullData 配列.
    useEffect(() => {
      setIsLoading(true);
    
      fetch(API_ENDPOINT)
        .then(response => response.json())
        .then(response => {
          setData(response.results);
    
          // ADD THIS
          setFullData(response.results);
    
          setIsLoading(false);
        })
        .catch(err => {
          setIsLoading(false);
          setError(err);
        });
    }, []);
    
    次に、ハンドラメソッドhandleSearch これは検索バーを処理する予定です.デフォルトでは、クエリとして提供される検索語を小文字にフォーマットします.ユーザの名前は状態変数からフィルタリングされるfullData 状態変数data 検索後に最終結果を格納し、正しいユーザーをレンダリングします.
    The contains ハンドラメソッドはクエリを探します.これは、ユーザの最初の名前と最後の名前と、handleSearch() .
    const handleSearch = text => {
      const formattedQuery = text.toLowerCase();
      const filteredData = filter(fullData, user => {
        return contains(user, formattedQuery);
      });
      setData(filteredData);
      setQuery(text);
    };
    
    const contains = ({ name, email }, query) => {
      const { first, last } = name;
    
      if (first.includes(query) || last.includes(query) || email.includes(query)) {
        return true;
      }
    
      return false;
    };
    
    今、シミュレータでは、検索クエリは、クエリに基づいて結果を取得します.

    結論


    このチュートリアルの焦点は、別の小道具に慣れて取得することでしたFlatList コンポーネントを提供します.
    などの強力な検索プロバイダーを使用することをお勧めしますAlgolia より良い結果のためにAPI終点からデータを取り出すとき.
    最後に、敏感なロジックを含む商業反応ネイティブアプリを開発している場合は特別な注意を払うことを忘れないでください.あなたは、コードの盗難、改ざん、およびリバースエンジニアリングから保護することができます次の.