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

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



<h1>完成形</h1>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820337/f6a7c188-1e1a-f65a-db73-67b18866870d.png">　　　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820337/18fcceee-0b9d-b1bd-4608-aafaf2f29414.png"> 

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

<h1>使用するライブラリ</h1>
・react-navigation：画面遷移機能
・react-native-paper：デザインツール



<br><br>



<h1>【本題】テンプレートの作成</h1>

<h3>手順１．新規プロジェクトの作成</h3>

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

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

途中出てくる選択肢は一番上の「blank」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820337/b4db2458-0112-040a-18d3-68fd9effa349.png)



<br><br>



<h3>手順２．Expoでプロジェクトを起動</h3>

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

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

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



<br><br>



<h3>手順３．画面遷移機能の導入</h3>
ライブラリはreact-navigationを使用します。
下のコマンドでreact-navigationとその他依存関係のあるライブラリをインストールします。

```ruby: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というライブラリを導入します。
(遷移先の画面が遷移元の画面の上にかぶさってくるもの)

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



<br><br>



<h3>手順４．デザインツールの導入</h3>
デザインツールにはマテリアルデザインができるreact-native-paperを使います。

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



<br><br>



<h3>手順５．プロジェクトを管理しやすくするため、src/component、src/screensフォルダを作成する。</h3>
```ruby:src/component、src/screensフォルダ作成
$ mkdir src
$ mkdir src/components 
$ mkdir src/screens
```
<br>
フォルダ構成はこのようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820337/44cc7312-7f3f-556e-c131-618541e6d8b2.png)

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



<br><br>



<h3>手順６．コードをコピペして画面を完成させる</h3>
ファイルを適宜作成しながら以下コードをコピペしたら完成です。

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


```ruby: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>
  );
}
```
<br>

```ruby: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>このページはPage１です</Text>
        <Button title="Page2へ" onPress={() => navigation.navigate('Page2')}></Button>
      </View>
    );
}
  
const styles = StyleSheet.create({
  container: {
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
  },
});

```
<br>

```ruby: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>このページはPage２です</Text>
      <Button title="Page1へ" onPress={() => navigation.navigate('Page1')}></Button>
    </View>
  );
}

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

```
<br>

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

```ruby: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>
  );
};
```
<br>

```ruby: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}
    />
  );
};
```

<br>

<h3>以上で完成です！</h3>

<br>