2017-01-03 9 views
0

私はReact Nativeで遊んで始めました。私は相対的な初心者です。 Navigatorコンポーネントを使用している問題が発生しており、何が起こっているかについて完全に迷っています。ネイティブナビゲーターに反応する - 最初のナビゲーションプッシュ後までレンダリングされないルート?

私は単純なマスター/詳細フローを設定しようとしています。最初の画面は、セルが少数のListViewだけで、セルをタップすると詳細画面が表示されます。詳細画面には、タップしたインデックスとマスター画面にポップバックするボタンを示す静的テキストが表示されます。

しかし、私は完全に奇妙な動作をしています - すべてのセル(最初のものを除く)の詳細画面は最初にレンダリングに失敗します。ナビゲータはブランク画面に移行するだけです。しかし、最初のディテール画面(正しくレンダリングする)をプッシュした後、ポップしてからもう一度押すと、画面の残りの部分が意図したとおりにうまく動作します。

index.ios.js:

import React, { Component } from 'react'; 
import { 
    AppRegistry, 
    StyleSheet, 
    Text, 
    View, 
    ListView, 
    Navigator, 
    TouchableOpacity, 
} from 'react-native'; 

//the navigation routes 
const routes = [ 
    {title: 'Main View', index: 0}, //the main screen with the list view 
    {title: 'Detail View 1', index: 1}, 
    {title: 'Detail View 2', index: 2}, 
    {title: 'Detail View 3', index: 3}, 
]; 

import MainList from './MainList' 

export default class ReactNativePractice extends Component { 

    componentDidMount(){ 
    console.log("master screen mounted") 
    } 

    //Navigator render scene function 
    renderScene = (route, navigator) => { 
    console.log("rendering route index: " + route.index) 
     if (route.index === 0){ //the main list. pass in routes and navigator as props. 
     return(
      <MainList 
      nav={navigator} 
      routes={routes}/> 
     ); 
     } 
     else{ //the detail screen. pass in route index and navigator as props. 
     var indexNum = route.index 
     return(
      <DetailView 
      num={indexNum} 
      nav = {navigator}/> 
     ); 
     } 
    } 

    render() { //main render function. Set up the navigator 
    return(
     <Navigator 
     initialRoute={routes[0]} 
     initialRouteStack={routes} 
     renderScene={this.renderScene} 
     /> 
    ); 
    } 
} 

//class for the detail view. Displays static text indicating the just-pressed index 
//and a button to go back to the main list. 
class DetailView extends Component{ 
    render(){ 
    return(
     <View style={styles.container}> 
     <Text>{this.props.num}</Text> 
     <TouchableOpacity 
      onPress={() => {this.props.nav.pop()}}> 
      <Text>Go back </Text> 
     </TouchableOpacity> 
     </View> 
    ); 
    } 
} 

//#####STYLESHEETS##### 
const styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    }, 
    row:{ 
    padding: 20, 
    marginBottom: 1, 
    backgroundColor: 'skyblue', 
    }, 
}); 

AppRegistry.registerComponent('ReactNativePractice',() => ReactNativePractice); 

MainList.js:私はコンソールにログに入れ

import React, { Component } from 'react'; 
import { 
    AppRegistry, 
    StyleSheet, 
    Text, 
    View, 
    ListView, 
    Navigator, 
    TouchableOpacity, 
} from 'react-native'; 

const rows = [ 
    {id: 0, text: 'row 1'}, 
    {id: 1, text: 'row 2'}, 
    {id: 2, text: 'row 3'}, 
] 
const rowHasChanged = (r1, r2) => r1.id !== r2.id 
const ds = new ListView.DataSource({rowHasChanged}) 
export default class MainList extends Component{ 

    state = { 
    dataSource: ds.cloneWithRows(rows) 
    } 

    //row pressed function- push the corresponding navigation route. 
    rowPressed = (rowData) =>{ 
    this.props.nav.push(this.props.routes[rowData.id+1]) //+1 because routes[0] is the main list view 

    } 

    renderRow = (rowData) => { 
    return(
     <TouchableOpacity 
     style={styles.row} 
     onPress={() => {this.rowPressed(rowData)}} 
     > 
     <Text>{rowData.text}</Text> 
     </TouchableOpacity> 
    ) 
    } 

    render(){ 
    return(
     <ListView 
     style={styles.container} 
     dataSource={this.state.dataSource} 
     renderRow={this.renderRow} 
     /> 
    ); 
    } 
} 

const styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    }, 
    row:{ 
    padding: 20, 
    marginBottom: 1, 
    backgroundColor: 'skyblue', 
    }, 
}); 

たびに呼び出されます。ここ

は私のコードですナビゲータのrenderScene関数が呼び出され、マスターコンポーネントが最初にマウントされたときに呼び出されます。コンソール上で私の出力を検査し、ここで私が得るものです:

アプリの起動時:

rendering route index: 0 
rendering route index: 1 
rendering route index: 2 
rendering route index: 3 
master screen mounted 

第1のナビゲーションプッシュのための任意のセルをクリックすると(それはどちらもかまいません):

rendering route index: 0 

は、私は、特に最初のセルをクリックした場合、今、私はマスターリストビューに戻って第1のナビゲーションポップをやろうとしている:

rendering route index: 0 

初めて飛び出ると、今再びプッシュしようと(今ではすべてのセルごとに完璧に動作します):何があっルートインデックス0が取得しているため

rendering route index: 0 
rendering route index: [correct index] 

明らかに、最初のプッシュで起こって何かがありますレンダリングされ、それ以外のものしかし、私は何が間違っているのか、ルート・インデックス1の最初の画面をとにかく表示しているようには思えません。

助力や洞察力があれば幸いです!ありがとうございました!

+0

おそらく 'this.renderScene.bind(this)'を試してみませんか? –

+0

@ NaderDabit 'Navigator'コンポーネントの' renderScene' propへの引数として、どこに置くのですか?私はちょうどそれを試み、それは行動に何の違いもありません。 – user2437424

+0

ああ、私はあなたが正しいと思う、違いはないはずです!私は、おそらくスタイリングか 'initialRouteStack'のどちらかと関係があるでしょう。 –

答えて

0

お試しください。 Santoshシャルマの答えのおかげで、私は実際に問題を突き止めましたのでindex.ios.js

NavigatorコンポーネントはMainList.js

import React, { Component } from 'react'; 
import { 
    AppRegistry, 
    StyleSheet, 
    Text, 
    View, 
    ListView, 
    Navigator, 
    TouchableOpacity, 
} from 'react-native'; 

const rows = [ 
    {id: 0, text: 'row 1'}, 
    {id: 1, text: 'row 2'}, 
    {id: 2, text: 'row 3'}, 
] 
const rowHasChanged = (r1, r2) => r1.id !== r2.id 
const ds = new ListView.DataSource({rowHasChanged}) 
export default class MainList extends Component{ 

constructor(props) { 
    super(props); 
    this.state = { 
    dataSource: ds.cloneWithRows(rows) 
    }; 
} 



    //row pressed function- push the corresponding navigation route. 
    rowPressed = (rowData) =>{ 
    this.props.nav.push(this.props.routes[rowData.id+1]) //+1 because routes[0] is the main list view 

    } 

    renderRow = (rowData) => { 
    return(
     <TouchableOpacity 
     style={styles.row} 
     onPress={() => {this.rowPressed(rowData)}} 
     > 
     <Text>{rowData.text}</Text> 
     </TouchableOpacity> 
    ) 
    } 

    render(){ 
    return(
     <ListView 
     style={styles.container} 
     dataSource={this.state.dataSource} 
     renderRow={this.renderRow} 
     /> 
    ); 
    } 
} 

const styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    }, 
    row:{ 
    padding: 20, 
    marginBottom: 1, 
    backgroundColor: 'skyblue', 
    }, 
}); 
+0

ありがとう、これは完璧に動作し、実際には私自身の答えに記載されているように、問題の原因を突き止めることができました。 – user2437424

+0

@ user2437424答えを受け入れてください。 –

0

<Navigator 
     style={{ flex:1 }} 
     ref={(nav) => { navigator = nav; }} 
     initialRoute={routes[0]} 
     renderScene={this.renderScene} 
    /> 

でなければなりません。なんらかの理由でinitialRouteinitialRouteStackの両方をNavigatorに渡していたのはこの問題の原因でした。私が単にinitialRouteを渡してinitialRouteStackを除外すると、それは最初と最後のプッシュで完全に動作します。誰もがこの理由の洞察を持っていますか?

関連する問題