【React Native入門】4-4 レイアウトを考える ナビゲーション

「React Native入門　掌田 津耶乃著」にて動作確認したコードを逐一まとめた記事です。
基本は自分用のメモですので、動作確認したい場合ご利用ください。
ある程度は1記事を更新していき、セッションが切り替わったら別記事に残していこうと思います。

目次
[ P.186〜P.195 ] 
・React Navigationについて
・createStackNavigatorの利用
・ナビゲーションを利用する
[ P.196〜P.201 ] タブナビゲーション

[ちょこっと一言]
ここを理解しておくと「ページ遷移」が可能になるので、
静的なアプリなら作れそうな感じがしました。

---

[ P.186〜P.195 ] 
・React Navigationについて
・createStackNavigatorの利用
・ナビゲーションを利用する

React Navigationの利用
追記
` import { createStackNavigator } from 'react-navigation'; ` 
↓
エラーになるかと思います。

Snack以外
package.jsonに以下追記

```json:package.json
"dependencies": {
 ...,
 "react-navigation": "2.11.2"
},
```

`npm install`

これでエラーはなくなり組み込み完了です。


# createStackNavigatorの利用

```js
export default createStackNavigator(
  {
    キー: { screen: コンポーネント },
    キー: { screen: コンポーネント },
    ...
  },
  {
    // ここで指定したページがファーストビューになる
    initialRouteName: 'キー',
  }
);
```

```js
// 指定画面に遷移
this.props.navigation.navigate('名前');

// 前に戻る
this.props.navigation.goBack();

// トップに戻る
this.props.navigation.popToTop();
```

```js:App.js
import React, { Component } from 'react';
import { StyleSheet, Alert, Modal, Button, StatusBar, TextInput, ScrollView, Text, View } from 'react-native';
import { Header, Tile } from 'react-native-elements';
import { createStackNavigator } from 'react-navigation';

// FirstScreen
class FirstScreen extends Component {
  static navigationOptions = {
    title: 'First Screen',
    headerStyle: {backgroundColor: '#aa0000'},
    headerTintColor: '#fff',
  };
  constructor(props) {
    super(props);
    this.state = {
      title: 'First Screen',
      message: 'This is Navigation Sample.',
    }
  }

  render() {
    return (
      <View style={styles.base}>
        <View style={ styles.body }>
          <Text style={ styles.title }>{ this.state.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>
          <View style={{ padding: 10 }}>
            <Button title="Next Screen >>" onPress={ this.doActionNext } />
          </View>
        </View>
      </View>
    );
  }

  doActionNext = () => {
    this.props.navigation.navigate('Next');
  }
} // FirstScreen

// SecondScreen
class SecondScreen extends Component {
  static navigationOptions = {
    title: 'Second Screen',
    headerStyle: {backgroundColor: '#00aa00'},
    headerTintColor: '#fff',
  };
  constructor(props) {
    super(props);
    this.state = {
      title: 'Second Screen',
      message: 'This is Navigation Sample.',
    }
  }

  render() {
    return (
      <View style={styles.base}>
        <View style={ styles.body }>
          <Text style={ styles.title }>{ this.state.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>
          <View style={{ padding: 10 }}>
            <Button title="<< Go Back" onPress={ this.doActionBack } />
          </View>
          <View style={{ padding: 10 }}>
            <Button title="Go Next >>" onPress={ this.doActionNext } />
          </View>
        </View>
      </View>
    );
  }

  doActionBack = () => {
    this.props.navigation.goBack();
  }
  doActionNext = () => {
    this.props.navigation.navigate('Last');
  }
} // SecondScreen

// ThirdScreen
class ThirdScreen extends Component {
  static navigationOptions = {
    title: 'thirdScreen Screen',
    headerStyle: {backgroundColor: '#0000aa'},
    headerTintColor: '#fff',
  };
  constructor(props) {
    super(props);
    this.state = {
      title: 'third Screen',
      message: 'This is Navigation Sample.',
    }
  }

  render() {
    return (
      <View style={styles.base}>
        <View style={ styles.body }>
          <Text style={ styles.title }>{ this.state.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>
          <View style={{ padding: 10 }}>
            <Button title="Go Home" onPress={ this.doActionHome } />
          </View>
        </View>
      </View>
    );
  }

  doActionHome = () => {
    this.props.navigation.popToTop();
  }
} // ThirdScreen

export default createStackNavigator(
  {
    Home: { screen: FirstScreen },
    Next: { screen: SecondScreen },
    Last: { screen: ThirdScreen },
  },
  {
    initialRouteName: 'Home',
  }
);

const styles = StyleSheet.create ({
  base: {
    padding: 0,
    flex: 1,
  },
  body: {
    padding: 10,
    flex: 1,
    backgroundColor: '#fff',
  },
  title: {
    padding: 10,
    color: 'red',
    fontSize: 48,
  },
  message: {
    padding: 10,
    fontSize: 28,
  }
});
```

# navigationOptionsについて

```js
static navigationOptions = {
    title: 'ヘッダータイトル',
    headerStyle: { プロパティ: 'ヘッダーのスタイル' },
    headerTintColor: 'ヘッダーテキストの色',
  };
```

---

[ P.196〜P.201 ] タブナビゲーション

```js
const Home = createBottomTabNavigator (
  {
    タブ表示名: { screen: コンポーネント },
    タブ表示名: { screen: コンポーネント },
    ...
  },
  {
    tabBarOptions: {
      activeTintColor: '選択されたタブテキストの色',
      inactiveTintColor: '選択されていないタブテキストの色',
      activeBackgroundColor: '選択されたタブ背景色',
      inactiveBackgroundColor: '選択されていないタブ背景色',
      labelStyle: {
        プロパティ: 表示されるタブテキストのスタイル,
      },
    }
  }
);
```

```js:App.js
import React, { Component } from 'react';
import { StyleSheet, Alert, Modal, Button, StatusBar, TextInput, ScrollView, Text, View } from 'react-native';
import { Header, Tile } from 'react-native-elements';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';

// FirstScreen
class FirstScreen extends Component {

  constructor(props) {
    super(props);
    this.state = {
      title: 'First Screen',
      message: 'This is Navigation Sample.',
    }
  }

  render() {
    return (
      <View style={styles.base}>
        <View style={ styles.body }>
          <Text style={ styles.title }>{ this.state.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>
        </View>
      </View>
    );
  }
} // FirstScreen

// SecondScreen
class SecondScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      title: 'Second Screen',
      message: 'This is Navigation Sample.',
    }
  }

  render() {
    return (
      <View style={styles.base}>
        <View style={ styles.body }>
          <Text style={ styles.title }>{ this.state.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>
        </View>
      </View>
    );
  }
} // SecondScreen

// ThirdScreen
class ThirdScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      title: 'Third Screen',
      message: 'This is Navigation Sample.',
    }
  }

  render() {
    return (
      <View style={styles.base}>
        <View style={ styles.body }>
          <Text style={ styles.title }>{ this.state.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>
        </View>
      </View>
    );
  }
} // ThirdScreen

// UserScreen(カスタマイズしてみた)
class UserScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      title: 'User Screen',
      message: 'This is Navigation Sample.',
    }
  }

  render() {
    return (
      <View style={styles.base}>
        <View style={ styles.body }>
          <Text style={ styles.title }>{ this.state.title }</Text>
          <Text style={ styles.message }>{ this.state.message }</Text>
        </View>
      </View>
    );
  }
} // UserScreen

const Home = createBottomTabNavigator (
  {
    Home: { screen: FirstScreen },
    Next: { screen: SecondScreen },
    Last: { screen: ThirdScreen },
    User: { screen: UserScreen },
  },
  {
    tabBarOptions: {
      activeTintColor: '#fff',
      inactiveTintColor: '#a9a9a9',
      activeBackgroundColor: '#1e90ff',
      inactiveBackgroundColor: '#dcdcdc',
      labelStyle: {
        fontSize: 14,
        padding: 15,
      },
    }
  }
);

export default class HomeScreen extends Component {
  render() {
    return(
      <View style={ styles.base }>
        <Header
          centerComponent={{
            text: 'SampleApp',
            style: styles.header
          }}
          outerContainerStyles={{
            height: 100,
            backgroundColor: '#dd0000'
          }}
        />
        <Text style={ styles.page }>
          This is Tab Sample.
        </Text>
        <Home />
      </View>
    );
  }
}

const styles = StyleSheet.create ({
  base: {
    padding: 0,
    flex: 1,
  },
  body: {
    padding: 10,
    flex: 1,
    backgroundColor: '#fff',
  },
  header: {
    color: '#fff',
    fontSize: 28,
    fontWeight: '100',
  },
  page: {
    paddingTop: 10,
    paddingLeft: 10,
    fontSize: 20,
  },
  title: {
    color: '#1e90ff',
    fontSize: 20,
  },
  message: {
    padding: 0,
    fontSize: 14,
  }
});
```