【React Native】初期テンプレート作成(画面遷移、ヘッダー、フッター)


すぐに開発が始められるように新規プロジェクト作成から、初期準備(画面遷移機能、デザインツールの導入)までの流れをまとめてます。

完成形

   

ヘッダー、フッター、画面遷移機能を入れただけのシンプルなものを作ります。

使用するライブラリ

・react-navigation:画面遷移機能
・react-native-paper:デザインツール



【本題】テンプレートの作成

手順1.新規プロジェクトの作成

新規プロジェクト作成
$ expo init note00

note00は作成したいプロジェクト名に置き換えてください。

途中出てくる選択肢は一番上の「blank」を選びます。



手順2.Expoでプロジェクトを起動

プロジェクト起動
$ cd note00  
$ expo start

自動で開くブラウザにQRコードが表示されるので、
自分のスマホにインストール済みのExpoアプリでQRコードを読み取れば、新規作成したプロジェクトが表示されます。

白紙ページの中央に
「Open up App.js to start working on your app!」
と表示されていれば成功です。



手順3.画面遷移機能の導入

ライブラリはreact-navigationを使用します。
下のコマンドでreact-navigationとその他依存関係のあるライブラリをインストールします。

react-navigationのインストール
$ yarn add @react-navigation/native
$ yarn expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view

今回、画面遷移時のアニメーションはもっともメジャーなstackというライブラリを導入します。
(遷移先の画面が遷移元の画面の上にかぶさってくるもの)

react-navigation/stackのインストール
$ yarn add @react-navigation/stack



手順4.デザインツールの導入

デザインツールにはマテリアルデザインができるreact-native-paperを使います。

react-native-paperのインストール
$ yarn add react-native-paper



手順5.プロジェクトを管理しやすくするため、src/component、src/screensフォルダを作成する。

src/component、src/screensフォルダ作成
$ mkdir src
$ mkdir src/components 
$ mkdir src/screens



フォルダ構成はこのようになります。

それぞれのフォルダは下のように使います。
src/components:部品になるコンポーネントを置くフォルダ(ヘッダー、フッターもここに入れます)
src/screens:1つの画面になるようなコンポーネントを保存します



手順6.コードをコピペして画面を完成させる

ファイルを適宜作成しながら以下コードをコピペしたら完成です。

※一部不思議なところで青文字になったりしてますが、気にせず全部コピペでOKです。

App.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import Header from './src/components/Header'
import Footer from './src/components/Footer'

import Page1 from './src/screens/Page1'
import Page2 from './src/screens/Page2'

const Stack = createStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator screenOptions={{header:Header}}>
        <Stack.Screen name="Page1" component={Page1} />
        <Stack.Screen name="Page2" component={Page2} />
      </Stack.Navigator>
      <Footer />
    </NavigationContainer>
  );
}


src/screens/Page1.js
import * as React from 'react';
import { StyleSheet,View, Text, Button } from 'react-native';

export default function Page1({ navigation }) {
    return (
      <View style={styles.container}>
        <Text>このページはPage1です</Text>
        <Button title="Page2へ" onPress={() => navigation.navigate('Page2')}></Button>
      </View>
    );
}

const styles = StyleSheet.create({
  container: {
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
  },
});


src/screens/Page2.js
import * as React from 'react';
import { StyleSheet,View, Text,Button } from 'react-native';

export default function Page2({ navigation }) {
  return (
    <View style={styles.container}>
      <Text>このページはPage2です</Text>
      <Button title="Page1へ" onPress={() => navigation.navigate('Page1')}></Button>
    </View>
  );
}

const styles = StyleSheet.create({
    container: {
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
    },
});


ヘッダーとフッターはreact-native-paperの公式ページからコードをまるまるコピペしてます。

src/components/Header.js
import * as React from 'react';
import { Appbar } from 'react-native-paper';



export default function Header() {
  const _goBack = () => console.log('Went back');
 const _handleSearch = () => console.log('Searching');
  const _handleMore = () => console.log('Shown more');

  return (
    <Appbar.Header>
      <Appbar.BackAction onPress={_goBack} />
      <Appbar.Content title="Title" subtitle="Subtitle" />
      <Appbar.Action icon="magnify" onPress={_handleSearch} />
      <Appbar.Action icon="dots-vertical" onPress={_handleMore} />
    </Appbar.Header>
  );
};


src/components/Footer.js
import * as React from 'react';
import { BottomNavigation,Text } from 'react-native-paper';



export default function Footer() {
  const MusicRoute = () => <Text>Music</Text>;
  const AlbumsRoute = () => <Text>Albums</Text>;
  const RecentsRoute = () => <Text>Recents</Text>;

  const [index, setIndex] = React.useState(0);
  const [routes] = React.useState([
    { key: 'music', title: 'Music', icon: 'queue-music' },
    { key: 'albums', title: 'Albums', icon: 'album' },
    { key: 'recents', title: 'Recents', icon: 'history' },
  ]);

  const renderScene = BottomNavigation.SceneMap({
    music: MusicRoute,
    albums: AlbumsRoute,
    recents: RecentsRoute,
  });

  return (
    <BottomNavigation
      navigationState={{ index, routes }}
      onIndexChange={setIndex}
      renderScene={renderScene}
    />
  );
};


以上で完成です!