8
7

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.

ReactNavigation V5 で画面遷移をクラスで行う方法

Last updated at Posted at 2020-07-11

環境

ReactNavigation V5

目的

やりたかったこと

  • ReactNavigation V5での画面遷移
  • App.jsにナビゲーションの設定がしてある
  • 各スクリーンは、クラスとして別ファイルに切り出し保持している

対応前のコード

ディレクトリ構成
App.js
screens
  画面1.js
  画面2.js
App.js
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import VID0 from './screens/画面1';
import VID1 from './screens/画面2';

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="画面1" component={画面1} />
        <Stack.Screen name="画面2" component={画面2} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

App:画面1
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';


class 画面1 extends React.Component {

  //スタートボタン押下時
  onStartButtonPress = () => {
    navigation.navigate('VID2'); //=> 注1
  }


  render() {
    return (
      <ScrollView
        <Button
        title='次へ'
        onPress={this.onStartButtonPress}
         />
      </ScrollView>
    );
  }
}
export default 画面1

問題

  • 子スクリーンが親のNavigationを取れず、遷移できない
  • 注1 の箇所 元々のReact-nativeのサンプルでは、functionであるため引数でnavigationを渡している

https://reactnavigation.org/docs/navigating

  • しかし、今回の場合クラスであるため、引数で渡せない

対策

https://reactnavigation.org/docs/use-navigation/

  • useNavigation ホックを利用すれば、navigationを取ることができる
  • 注意点として、このホックを使えるのは、関数内だけであるため、class中では使えない
  • 以下のエラーが発生する
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
  • そのため、関数でクラスをラップする

やること

  • useNavigation をインポートする
  • classを関数でWrapし、関数の方をexport default する
  • class のexport defaultを消す
  • export defaultする関数を作る
  • 関数の中で useNavigation() を行い、navigationを取得する
  • 関数はpropsを引数にとり、画面のクラスをreturnする。この時propsにnavigationを渡す
  • クラスは、遷移イベント時に、this.propsからnavigationを取得する

対応後のコード

App:画面1
// ============ useNavigationを追加
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

//===ここでfunctionでクラスをWrap こっちをexport defaultする

export default function(props) {

//=== useNavigationを取得し、クラスにnavigationを渡す
  const navigation = useNavigation();

  return <画面1 {...props} navigation={navigation} />;
}

//=====exportしない
class 画面1 extends React.Component {

  //スタートボタン押下時
  onStartButtonPress = () => {
//=======関数から渡されたpropsのnavigationを取得し、利用する
    const { navigation } = this.props;
    navigation.navigate('VID2');
  }


  render() {
    return (
      <ScrollView
        <Button
        title='次へ'
        onPress={this.onStartButtonPress}
         />
      </ScrollView>
    );
  }
}

8
7
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
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?