0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Expo+Redux(+firebase)でログインフォーム④ 〜ReactNavigationを使った画面遷移〜

Last updated at Posted at 2020-02-22

はじめに

Expo+Redux(+firebase)でログインフォーム③ 〜ファイル整理・Debugger〜 の続きです。
この記事では、ログイン画面を作り、ReactNavigationで画面遷移をできるようにしていきます。
まだログインのロジック自体は実装していないので、ボタンをクリックすると画面遷移されるようにしておきます。

画面構成

スクリーンショット 2020-02-22 12.05.48.png

React Navigation

2020/2/22時点での最新は5.xです
3.xや4.xとは文法が変わっているので、ネットの記事を参考にする際は注意してください!!(僕はこれでハマりました)

Reduxとの共存ですが、App.tsxとコンポーネントをいじるだけで使えるようになります。
storeやmodulesを気にせず使えるので便利ですね

App

src/App.tsx
import React from 'react';
import { Provider } from 'react-redux'
import { NavigationContainer } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'
import store from './store'
import CounterContainer from './containers/Counter'
import StaticCounterContainer from './containers/StaticCounter'
import SigninContainer from './containers/Signin'
import SignupContainer from './containers/Signup'


export default function App() {
  // サインイン中のScreen
  const SignedInStack = createStackNavigator()

  const SignedInStackScreen = () => {
    return (
      <SignedInStack.Navigator>
        <SignedInStack.Screen name='Counter' component={CounterContainer} />
        <SignedInStack.Screen name='StaticCounter' component={StaticCounterContainer} />
      </SignedInStack.Navigator>
    )
  }

  // サインアウト後のスクリーン(Auth関連の画面)
  const SignedOutStack = createStackNavigator()

  const SignedOutStackScreen = () => {
    return (
      <SignedOutStack.Navigator>
        <SignedOutStack.Screen name='Signin' component={SigninContainer} />
        <SignedOutStack.Screen name='Signup' component={SignupContainer} />
      </SignedOutStack.Navigator>
    )
  }

  // RootのScreen(ローディング画面、サインイン中、サインアウト後)
  const RootStack = createStackNavigator()

  const RootStackScreen = () => (
    <RootStack.Navigator>
      <RootStack.Screen name='SignedIn' component={SignedInStackScreen} options={{ headerShown: false }}/>
      <RootStack.Screen name='SignedOut' component={SignedOutStackScreen} options={{ headerShown: false }} />
    </RootStack.Navigator>
  )
  return (
    <Provider store={store}>
      <NavigationContainer>
        <RootStackScreen />
      </NavigationContainer>
    </Provider>
  )
}

StackNavigationを使用しています
createStackNavigator()で各スクリーンのナビゲーターを作り、それを使ってスクリーンを作っています。
ログイン中とログアウト中のスクリーンをそれぞれ作ったら、それらをcomponentとしてRootStackに渡してまとめることで、ネストしたルーティングを実現します。

src/App.tsx
  return (
    <Provider store={store}>
      <NavigationContainer>
        <RootStackScreen />
      </NavigationContainer>
    </Provider>
  )

Providerの内側にNavigationContainerを置くのを忘れないようにしましょう。

Containers

Signup.tsx

src/containers/Signup.ts
import { connect } from 'react-redux'
import Signup from '../components/Signup'

const SignupContainer = connect()(Signup)

export default SignupContainer

Signup画面では、使うpropsはnavigationだけですが、これはconnect関数に渡さなくともReactNavigationがよしなにしてくれるっぽいです。なので、mapStateToProps, dispatchToPropsは共に使いません。
Signin.tsもほぼこれと変わらないので、省略します。
Counter.tsは前回の記事から変更はありません。

Components

Signup.tsx

src/components/Signup.tsx
import React from 'react'
import { View, Text, Button } from 'react-native'
import styles from '../Styles'

const Signup = ({ navigation }) => (
  <View style={styles.container}>
    <Text style={styles.paragraph}>Signup</Text>
    <Button
      title='Go to Signin'
      onPress={() => navigation.navigate('Signin')}
    />
    <Button
      title='Go to Counter'
      onPress={() => navigation.navigate('Counter')}
    />
  </View>
)

export default Signup

propでnavigationを受け取っています。これはContainerから受け取ったものではなくReactNavigationが提供しているものです。
画面遷移するには、navigation.navigate()に移動したいスクリーンの名前を渡します。
navigate()だけでなく、goBack()等あるので、公式ドキュメントを参考に。

Counter.tsx

src/components/Counter.tsx
import React from 'react'
import { View, Text, Button } from 'react-native'
import styles from '../Styles'

const Counter = ({ count, increment, decrement, navigation }) => (
  <View style={styles.container}>
    <Text style={styles.paragraph}>{count}</Text>
    <Button
      title='Increment'
      onPress={increment}
    />
    <Button
      title='DECREMENT'
      onPress={decrement}
    />
    <Button
      title='Go to Static Count page'
      onPress={() => navigation.navigate('StaticCounter')}
    />
    <Button
      title='Go to SignedOut'
      onPress={() => navigation.navigate('SignedOut', { screen: 'Signup' } )}
    />
  </View>
)

export default Counter

Signup.tsxとあまり変わらないですね。
'Go to SignedOut'のコールバックのように、ネストした深いスクリーンまで指定して画面遷移したい場合は、スクリーンの名前の後に、paramsに{ screen: "スクリーンの名前" }を加えると実現できます。
ここで、いきなりnavigation.navigate('Signup')とすると、スクリーンが見つからずエラーになるので気をつけましょう。

次回

上と同じようにSignin画面、StaticCounter画面を作れば、ボタンを押すことで画面遷移を行えるようになりました。
次回では、フォームの作成とfirebaseのAuthenticationを用いたパスワード認証を実装していきましょう。
Expo+Redux(+firebase)でログインフォーム⑤ 〜入力フォームとログインロジックの実装〜

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?