質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

6284閲覧

react navigationの遷移が出来ない (react native)

退会済みユーザー

退会済みユーザー

総合スコア0

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2018/06/24 19:25

編集2018/06/24 19:31

前提・実現したいこ

App.jsに定義している各PageにStartButtonを用いて画面遷移を行えるようにしたい

reactnavigationを使って画面遷移しようとするとiosSimulatorで TypeError: undefined is not an object (evaluating 'this.props.navigation.navigate')のエラーコードが出る。

エラーメッセージ

TypeError: undefined is not an object (evaluating 'this.props.navigation.navigate')

App.js

import { StackNavigator } from 'react-navigation'; import swipePage from './src/screens/swipePage'; import tinder from './src/screens/tinder'; import tinderResult from './src/screens/tinderResult'; const App = StackNavigator({ Page1: { screen: swipePage }, Page2: { screen: tinder }, page3: { screen: tinderResult }, }); export default App;

StartButton.js

import React from 'react'; import { StyleSheet, View, Text, TouchableHighlight } from 'react-native'; class StartButton extends React.Component { render() { const { onPress } = this.props; return ( <View> <TouchableHighlight onPress={onPress}> <View style={styles.startButtonstyle}> <Text style={styles.startButtontext}>Tap to start</Text> </View> </TouchableHighlight> </View> ); } } export default StartButton;

swipePage.js

import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; import Swiper from 'react-native-swiper'; import StartButton from '../elements/StartButton'; export default class App extends React.Component { render() { const { navigate } = this.props.navigation; return ( <Swiper showsButtons loop={false}> <View style={styles.slide}> <Text style={styles.text}>First Page</Text> </View> <View style={styles.slide}> <Text style={styles.text}>Second Page</Text> </View> <View style={styles.slide}> <Text style={styles.text}>Third Page</Text> </View> <View style={styles.slide}> <StartButton onPress={() => { navigate('Page2'); }} /> </View> </Swiper> ); } }

tinder.js

import React from 'react'; import { StyleSheet, Text, View, Image } from 'react-native'; import SwipeCards from 'react-native-swipe-cards'; import StartButton from '../elements/StartButton'; class Card extends React.Component { constructor(props) { super(props); } render() { return ( <View style={styles.card}> <Image style={styles.thumbnail} source={{uri: this.props.image}} /> </View> ) } } class NoMoreCards extends React.Component { constructor(props) { super(props); } render() { const { navigate } = this.props.navigation; return ( <View> <View style={styles.noMoreCards}> <Text>No more cards</Text> </View> <View> <StartButton onPress={() => { navigate('Page3'); }} /> </View> </View> ) } } const cards = [ {name: '1', image: 'https://media.giphy.com/media/GfXFVHUzjlbOg/giphy.gif'}, {name: '2', image: 'https://media.giphy.com/media/irTuv1L1T34TC/giphy.gif'}, {name: '3', image: 'https://media.giphy.com/media/LkLL0HJerdXMI/giphy.gif'}, {name: '4', image: 'https://media.giphy.com/media/fFBmUMzFL5zRS/giphy.gif'}, ] const cards2 = [ {name: '10', image: 'https://media.giphy.com/media/12b3E4U9aSndxC/giphy.gif'}, {name: '11', image: 'https://media4.giphy.com/media/6csVEPEmHWhWg/200.gif'}, ] export default class App extends React.Component { constructor(props) { super(props); this.state = { cards: cards, outOfCards: false } } handleYup (card) { console.log("yup") } handleNope (card) { console.log("nope") } cardRemoved (index) { console.log(`The index is ${index}`); let CARD_REFRESH_LIMIT = 3 if (this.state.cards.length - index <= CARD_REFRESH_LIMIT + 1) { console.log(`There are only ${this.state.cards.length - index - 1} cards left.`); if (!this.state.outOfCards) { console.log(`Adding ${cards2.length} more cards`) this.setState({ cards: this.state.cards.concat(cards2), outOfCards: true }) } } } render() { return ( <SwipeCards cards={this.state.cards} loop={false} renderCard={cardData => <Card {...cardData} />} renderNoMoreCards={() => <NoMoreCards />} showYup={true} showNope={true} handleYup={this.handleYup} handleNope={this.handleNope} cardRemoved={this.cardRemoved.bind(this)} /> ) } }

試したこと

各PageにStartButtonを呼び出してそこから画面遷移させている。
Page1からPage2は問題なく画面遷移が行えるが、Page2からPage3に画面遷移させようとするとエラーコードが返されてしまう

補足情報(FW/ツールのバージョンなど)

Page2で使用しているライブラリ 
https://github.com/meteor-factory/react-native-tinder-swipe-cards

初学者なものでなかなか解決できず、どうか御願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

前提

※ ローカル環境を作って動作確認はしていないので、あくまで参考程度にしてください。

回答

import swipePage from './src/screens/swipePage'; import tinder from './src/screens/tinder'; const App = StackNavigator({ Page1: { screen: swipePage }, Page2: { screen: tinder } });

まず、前提となる基本部分を確認していきましょう。

上記コードを見る限り、Page1に該当するswipePageswipePage.js内のAppコンポーネントであり、Page2に該当するtindertinder.jsAppコンポーネントになります。

コンポーネント内でthis.props.navigationのようにreact-navigationライブラリのnavigationオブジェクトを参照出来るのは、StackNavigatorメソッドの引数に渡している設定オブジェクトに含まれたコンポーネントのみになります。

class NoMoreCards extends React.Component { constructor(props) { super(props); } render() { // !!! ここでログを確認してみましょう。 console.log(this.props.navigation); const { navigate } = this.props.navigation; return ( <View> 省略 </View> ) } }

しかし、NoMoreCardsコンポーネントは先ほどのStackNavigatorの引数に渡される設定オブジェクトでは、遷移可能なscreenとして定義されていないのにも関わらず、上記のコードでは、this.props.navigationのようにnavigationオブジェクトを参照しようとしてしまっています。

おそらく、エラーが出ているのは丁度、この部分になるかと思います。

では、どうすれば良いのか?

export default class App extends React.Component { // 省略 render() { // ここでnavigationに参照可能なことを確認してみましょう。 console.log(this.props.navigation); return ( <SwipeCards // 省略 renderNoMoreCards={() => <NoMoreCards />} // 省略 /> // 省略 ) } }

tinder.js内のAppコンポーネントは、App.js内のStackNavigator()で遷移可能なPage2として定義されており、this.props.navigationも参照可能なはずですから、Appコンポーネントが受け取るthis.props.navigationを子コンポーネントであるNoMoreCardsコンポーネントにpropsを通して渡してあげれば、NoMoreCardsコンポーネント内でthis.props.navigationとして参照が可能になるはずです。

renderNoMoreCards={() => <NoMoreCards navigation={this.props.navigation} />}

例えば、こんな感じで。

冒頭で述べた通り、動作確認をしていないので、他に今回の質問とは関係ない部分のエラーが出たり、そもそも、この回答が間違っている可能性もありますが、回答コードに差し込んだconsole.log(this.props.navigation)の値を確認して参考にしてみてください。

投稿2018/06/25 00:33

編集2018/06/25 00:35
HayatoKamono

総合スコア2415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/06/25 08:30

問題なく遷移させることができました。 問題を解決するアプローチからすごく参考になりました。 有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問