準備
今回はexpコマンドを利用してみます。create-react-native-appでも基本は同じ。
exp init stack
>blank
cd stack
npm install --save react-navigation
You must install peer dependencies yourselfというWarningが沢山でますが、無視(動作に問題ないようです)。
基本実装
実装していきます。はじめから存在しているApp.jsを編集していきます。編集は下から上に進む感じです。
シンプルでわかりやすいですね。
import React from 'react';
import { Button, View, Text } from 'react-native';
import { createStackNavigator } from 'react-navigation';
//About
class AboutScreen extends React.Component{
render() {
return (
<View style={{flex:1, alignItems: 'center', justifyContent: 'center'}}>
<Text>About</Text>
</View>
);
}
}
//Home
class HomeScreen extends React.Component{
render(){
return (
<View style={{flex:1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Home</Text>
<Button
title='Link to About'
onPress={() => this.props.navigation.navigate('About')}
/>
</View>
);
}
}
//RootStack
const RootStack = createStackNavigator(
{
Home: {
screen: HomeScreen,
},
About: {
screen: AboutScreen,
}
},
{
initialRouteName: 'Home',
}
);
//App
export default class App extends React.Component {
render() {
return (
<RootStack/>
);
}
}
Screen間での値の受け渡し
いくつかのやり方があるようですが、今回はPropsとGlobal変数を利用するやり方を検証してみます。
今回はReduxは使わないでおきます。
props
受け渡し(送信)は、リンクの際のthis.props.navigation.navigate('About',{Data})の第二引数に指定します。
受け取りは、this.props.navigation.state.params.Dataという感じで取得できるようです。
import React from 'react';
import { Button, View, Text } from 'react-native';
import { createStackNavigator } from 'react-navigation';
class AboutScreen extends React.Component{
render() {
return (
<View style={{flex:1, alignItems: 'center', justifyContent: 'center'}}>
<Text>About</Text>
+ <Text>{this.props.navigation.state.params.User.name}</Text> //受け取り
</View>
);
}
}
class HomeScreen extends React.Component{
render(){
return (
<View style={{flex:1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Home</Text>
<Button
title='Link to About'
+ onPress={() => this.props.navigation.navigate('About',{User:{name: 'hoge', age: 33}})} //送信
/>
</View>
);
}
}
const RootStack = createStackNavigator(
{
Home: {
screen: HomeScreen,
},
About: {
screen: AboutScreen,
}
},
{
initialRouteName: 'Home',
}
);
export default class App extends React.Component {
render() {
return (
<RootStack/>
);
}
}
Globals.js
ここに書いているやり方です。そのまま利用させていただきます。
まず、App.jsと同じ階層にGlobals.jsを作成し、下記の記述をします。
export default {
STORE_KEY: 'a56z0fzrNpl^2',
BASE_URL: 'http://someurl.com',
COLOR: {
ORANGE: '#C50',
DARKBLUE: '#0F3274',
LIGHTBLUE: '#6EA8DA',
DARKGRAY: '#999',
},
};
App.jsにてGlobals.jsを読み込みます。
import React from 'react';
import { Button, View, Text } from 'react-native';
import { createStackNavigator } from 'react-navigation';
+import GLOBALS from './Globals';
class AboutScreen extends React.Component{
render() {
return (
<View style={{flex:1, alignItems: 'center', justifyContent: 'center'}}>
<Text>About</Text>
<Text>{this.props.navigation.state.params.User.name}</Text>
+ <Text>{GLOBALS.COLOR.ORANGE}</Text>
</View>
);
}
}
class HomeScreen extends React.Component{
render(){
return (
<View style={{flex:1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Home</Text>
<Button
title='Link to About'
onPress={() => this.props.navigation.navigate('About',{User:{name: 'hoge', age: 33}})}
/>
+ <Text>{GLOBALS.COLOR.ORANGE}</Text>
</View>
);
}
}
const RootStack = createStackNavigator(
{
Home: {
screen: HomeScreen,
},
About: {
screen: AboutScreen,
}
},
{
initialRouteName: 'Home',
}
);
export default class App extends React.Component {
render() {
return (
<RootStack/>
);
}
}
どちらのScreenでも#C50という設定値が参照できています。
値を更新してみる
Globals.js内の値は普通に?更新可能です。
とりあえずDidMountで更新してみます(もちろん元ファイルが書き換わるわけではありません)。
import React from 'react';
import { Button, View, Text } from 'react-native';
import { createStackNavigator } from 'react-navigation';
import GLOBALS from './Globals';
class AboutScreen extends React.Component{
render() {
return (
<View style={{flex:1, alignItems: 'center', justifyContent: 'center'}}>
<Text>About</Text>
<Text>{this.props.navigation.state.params.User.name}</Text>
<Text>{GLOBALS.COLOR.ORANGE}</Text>
</View>
);
}
}
class HomeScreen extends React.Component{
render(){
return (
<View style={{flex:1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Home</Text>
<Button
title='Link to About'
onPress={() => this.props.navigation.navigate('About',{User:{name: 'hoge', age: 33}})}
/>
<Text>{GLOBALS.COLOR.ORANGE}</Text>
</View>
);
}
}
const RootStack = createStackNavigator(
{
Home: {
screen: HomeScreen,
},
About: {
screen: AboutScreen,
}
},
{
initialRouteName: 'Home',
}
);
export default class App extends React.Component {
+ componentDidMount(){
+ GLOBALS.COLOR.ORANGE = '#FFFFFF';
+ }
render() {
return (
<RootStack/>
);
}
}
上記の実装の場合、HomeのGLOBALS.COLOR.ORANGEの値は#C50となり、Aboutの値は#FFFFFFとなります。setState()ではないので、自動的に更新されたりはしないので注意が必要です(componentWillMount()に実装すれば、どちらも#FFFFFFとなります)。