react-nativeを使ったアプリ(react-native-cli)で、react-native-router-flux、native-baseを使ったアプリケーションの土台作りと、ライブラリ特有のルール等のメモ。
パッケージインストール
react-native-router-fluxのインストール
npm i -save react-native-router-flux
私の環境では上記だけではreact-native-router-fluxでの画面遷移が上手くいかず、以下のエラーが発生。
Unable to resolve module ‘react-native-screen’
こんな感じのエラーが出てしまい、以下のライブラリが必要だったので追加しました。
npm i --save react-native-gesture-handler react-native-reanimated react-native-screens
native-baseのインストール
npm i --save native-base
react-native-router-fluxを使った画面遷移のシンプルな例
各ページをwrapするコンポーネントを定義する
import React, {Component} from 'react';
import { Scene, Router } from 'react-native-router-flux';
import Home from './page/Home';
import MyPage from './page/MyPage';
export default class Wrapper extends Component {
render() {
return (
<Router>
<Scene>
<Scene key="Home"
component={Home}
initial
/>
<Scene key="MyPage"
component={MyPage}
/>
</Scene>
</Router>
);
}
}
各ページを定義する
import React, {Component} from 'react';
import { Container, Header,Content, Left, Body, Right, Button, Icon, Title } from 'native-base';
import FooterArea from './Sections/FooterArea';
export default class Home extends Component {
render() {
return (
<Container>
<Header>
<Left>
<Button transparent}>
<Icon name='menu' />
</Button>
</Left>
<Body>
<Title>Header</Title>
</Body>
<Right />
</Header>
<Content/>
<FooterArea/>
</Container>
);
}
}
import React, { Component } from 'react';
import {Container,Header,Title,Content, Button,Left,Right,Body,Icon} from 'native-base';
import { Actions } from 'react-native-router-flux';
import FooterArea from './Sections/FooterArea';
class MyPage extends Component {
render() {
return (
<Container>
<Header>
<Left>
<Button transparent>
<Icon name='arrow-back'
onPress={ () => Actions.Mypage() }
/>
</Button>
</Left>
<Body>
<Title>タイトル</Title>
</Body>
<Right>
<Button transparent>
<Icon name='menu' />
</Button>
</Right>
</Header>
<Content>
</Content>
<FooterArea/>
</Container>
)
}
}
export default MyPage;
import React, { Component } from 'react';
import { Text } from 'react-native';
import {Footer, Button,Icon} from 'native-base';
import { Actions } from 'react-native-router-flux';
class FooterArea extends Component {
render() {
return (
<Footer>
<Button active
onPress={ () =>Actions.Home()}
>
<Icon ios='ios-paper' android="md-paper" />
<Text >Home</Text>
</Button>
<Button
onPress={ () =>Actions.MyPage()}
>
<Icon ios='ios-bookmark' android="md-bookmark" />
<Text >MyPage</Text>
</Button>
</Footer>
)
}
}
export default FooterArea;
実装の際にいくつか気づいたポイント
react-native特有というか、パッケージ特有の指定の仕方など。
react-native-router-fluxのヘッダーを使用しない
react-native-router-fluxを使うとデフォルトで”ヘッダーのナビゲーション”が付いてきますが、ヘッダーはnative-baseに任せたかったので非表示にしたかった。
sceneにhideNavBar={true}を追加します。
<Scene key="Home"
component={Home}
initial
hideNavBar={true}
/>
これでOK
react-native-router-fluxで前の画面に戻る
Actions.pop()を使う。
いまの画面を更新するにはActions.refresh()
react-native-router-fluxのonEnter、onExitについて
Sceneに追加することができるメソッドで、Sceneが表示されたときにonEnter、シーンが切り替わったとき(非表示になったとき)にonExitでイベントを仕込むことができる。
native-baseのheaderを透明にする
<Header
transparent
>
transparentを追加するだけ
native-baseでのmarginやpaddingの指定など
bootstrap4に馴染みがあると「col-**」といった感じで手軽にできるのかなーと思っていましたが、特になさそう。
以下のように各コンポーネントにStyleSheetで定義するようにしました。
import { StyleSheet } from 'react-native';
class *** extends Component {
~~~
<Container style={style.container}>
</Container>
}
export default ***
const style = StyleSheet.create({
container: {
backgroundColor: '#eee'
},
});
native-baseで使えるフォントなど
デフォルトでも以下に載っているものは指定できるよう。
https://github.com/react-native-training/react-native-fonts
native-baseで初めから使えるアイコン群
react-nativeで背景画像を設定する方法
大きく2通り
react-nativeのImageをImportし、スタイルで背景画像として割り当てる
import { Image} from 'react-native';
・
・
<Image
source={require('../***.png')}
style={{position: 'absolute', bottom: 0, zIndex: -1}}
/>
react-nativeのImageBackgroundを使用する
import { ImageBackground,StyleSheet } from 'react-native';
・
・
<ImageBackground source={require('../***.jpg')} style={style.image}>
</ImageBackground>
const style = StyleSheet.create({
image: {
flex: 1,
resizeMode: "cover",
justifyContent: "center",
paddingBottom:20
}
})
ButtonのイベントにはonPressを使う
webでreactを使うのに慣れているとついonClickでもいけちゃうと思いますが、onClickではなくonPressを使う