2016-07-29 14 views
5

私はreact-nativeを使用する方法を学びたいので、サーバーからユーザーのリストを取得し、listviewに表示する小さなアプリケーションを入れています行を押すと、ユーザーのデータを表示する画面が開きます。React-native - ある画面から別の画面にデータを渡す

1つの画面から別の画面に移動するためのナビゲータを設定しました。行を押すと新しい画面を開くことができますが、この新しい画面にデータを渡す方法はわかりません。

私はボタンを押した後、私が使用されるいくつかのJSONデータをフェッチ、ボタン、空リストビュー(ContactList.js)で画面を表示index.android.js

import React from 'react'; 
import { 
    AppRegistry, 
    Navigator, 
} from 'react-native'; 

import ContactList from './src/containers/ContactList.js'; 

function MyIndex() { 
    return (
    <Navigator 
     initialRoute={{ name: 'index', component: ContactList }} 
     renderScene={(route, navigator) => { 
     if (route.component) { 
      return React.createElement(route.component, { navigator }); 
     } 

     return undefined; 
     }} 
    /> 
); 
} 

AppRegistry.registerComponent('reactest',() => MyIndex); 

最初にナビゲータを設定しますlistviewを更新:

import React, { Component, PropTypes } from 'react'; 
import { 
    Text, 
    View, 
    TouchableOpacity, 
    TouchableHighlight, 
    ListView, 
    Image, 
} from 'react-native'; 

import styles from '../../styles'; 
import ContactDetails from './ContactDetails'; 

const url = 'http://api.randomuser.me/?results=15&seed=azer'; 

export default class ContactList extends Component { 
    static propTypes = { 
    navigator: PropTypes.object.isRequired, 
    } 
    constructor(props) { 
    super(props); 

    const datasource = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); 
    this.state = { 
     jsonData: datasource.cloneWithRows([]), 
     ds: datasource, 
    }; 
    } 
    _handlePress() { 
    return fetch(url) 
     // convert to json 
     .then((response) => response.json()) 
     // do some string manipulation on json 
     .then(({ results }) => { 
     const newResults = results.map((user) => { 
      const newUser = { 
      ...user, 
      name: { 
       title: `${user.name.title.charAt(0).toUpperCase()}${user.name.title.slice(1)}`, 
       first: `${user.name.first.charAt(0).toUpperCase()}${user.name.first.slice(1)}`, 
       last: `${user.name.last.charAt(0).toUpperCase()}${user.name.last.slice(1)}`, 
      }, 
      }; 

      return newUser; 
     }); 

     return newResults; 
     }) 
     // set state 
     .then((results) => { 
     this.setState({ 
      jsonData: this.state.ds.cloneWithRows(results), 
     }); 
     }); 
    } 
    renderRow(rowData: string) { 
    return (
     <TouchableHighlight 
     onPress={() => { 
      this.props.navigator.push({ 
      component: ContactDetails, 
      }); 
     }} 
     > 
     <View style={styles.listview_row}> 
      <Image 
      source={{ uri: rowData.picture.thumbnail }} 
      style={{ height: 48, width: 48 }} 
      /> 
      <Text> 
      {rowData.name.title} {rowData.name.first} {rowData.name.last} 
      </Text> 
     </View> 
     </TouchableHighlight> 
    ); 
    } 
    render() { 
    const view = (
     <View style={styles.container}> 
     <TouchableOpacity 
      onPress={() => this._handlePress()} 
      style={styles.button} 
     > 
      <Text>Fetch results?</Text> 
     </TouchableOpacity> 
     <ListView 
      enableEmptySections 
      dataSource={this.state.jsonData} 
      renderRow={(rowData) => this.renderRow(rowData)} 
      onPress={() => this._handleRowClick()} 
     /> 
     </View> 
    ); 

    return view; 
    } 
} 

行が押下されると、それはユーザのデータを表示するようになっている新しい画面ContactDetails.js、開き:

未定義の私のような多くのことを試してみました( 'this.props.title' を評価)オブジェクト

ではありません。私はこのエラーが得たこの時点で

import React, { 
} from 'react'; 

import { 
    Text, 
    View, 
} from 'react-native'; 

import styles from '../../styles'; 

export default function ContactDetails() { 
    return (
    <View style={styles.container}> 
     <Text>{this.props.title}</Text> 
     <Text>{this.props.first}</Text> 
     <Text>{this.props.last}</Text> 
    </View> 
); 
} 

this.props.navigator.push({ 
    component: ContactDetails, 
    title: rowData.name.title, 
    first: rowData.name.first, 
    last: rowData.name.last, 
}); 

または

this.props.navigator.push({ 
    component: ContactDetails, 
    props: { 
     title: rowData.name.title, 
     first: rowData.name.first, 
     last: rowData.name.last, 
    } 
}); 

または

this.props.navigator.push({ 
    component: ContactDetails, 
    passProps: { 
     title: rowData.name.title, 
     first: rowData.name.first, 
     last: rowData.name.last, 
    } 
}); 

しかし無駄に。

私もreduxを使うべきだと読んだ。私は何か間違っているのですか?

EDIT:問題はここにある:

<TouchableHighlight 
    onPress={() => { 
     this.props.navigator.push({ 
     component: ContactDetails, 
     }); 
    }} 
> 

私はそこにいくつかのパラメータを渡す必要があると仮定し、私は上記試したどんな失敗しました。

答えて

5

:私は非常にルーティングするために、このライブラリを使用することをお勧めあなたのroute.propsまたはroute.passPropsを渡さないでください。そして、その時点でNavigatorのソースに表示されているものから、あなたが作成したときに完全なルートオブジェクトを持っているはずです。だからあなたはあなたの小道具を渡すことができるはずです。例えば

<Navigator 
    initialRoute={{ name: 'index', component: ContactList }} 
    renderScene={(route, navigator) => { 
    if (route.component) { 
     return React.createElement(route.component, { navigator, ...route.props }); 
    } 

    return undefined; 
    }} 
/> 

// push 
<TouchableHighlight 
    onPress={() => { 
    this.props.navigator.push({ 
     component: ContactDetails, 
     props: { /* ... */ } 
    }); 
    }} 
> 

あなたは可能性もセットアップReduxの、それは必要条件ではありません。あなたのアプリがより大きくなるなら、あなたは本当に外部の店を使うことを検討すべきです!


更新:

別の問題もあります。

機能コンポーネントを使用しています。機能コンポーネントにはthisはありません。彼らはパラメータで小道具を受け取る。

だから、このようにする必要があります:

export default function ContactDetails(props) { 
    return (
    <View style={styles.container}> 
     <Text>{props.title}</Text> 
     <Text>{props.first}</Text> 
     <Text>{props.last}</Text> 
    </View> 
); 
} 
+0

の解決策を見つけたいと思っていますが、問題は別の部分にあります。 – vincenth

+0

@vincenth実際には両方が必要です。あなたのrenderScene関数は現在、パラメータを渡しません。例として、route.propsをコンポーネントに配布しています。したがって、navigator.pushで「小道具」と呼ぶと、renderSceneで小道具を渡す必要があります。あなたがpassPropsを呼び出すならpassPropsを渡すべきです。 –

+0

@vincenth私の更新を見てください。 ContactDetailsコンポーネントに別の問題が見つかりました。 –

1

私はまだデフォルトのナビゲーションが煩わしいと感じています。 renderScene機能で

<Navigator 
    initialRoute={{ name: 'index', component: ContactList }} 
    renderScene={(route, navigator) => { 
    if (route.component) { 
     return React.createElement(route.component, { navigator }); 
    } 

    return undefined; 
    }} 
/> 

を、あなたがルートを受け取る(とroute.componentを使用)しますが、あなた:だから問題はここにあるように思わhttps://github.com/aksonov/react-native-router-flux

+0

提案をお寄せいただきありがとうございます。私は間違いなく試してみたいと思っています。最初に – vincenth

0

置き換えコード:付き

<TouchableOpacity 
     onPress={() => this._handlePress()} 
     style={styles.button} 
> 

<TouchableOpacity 
     onPress={() => this._handlePress()} 
     style={styles.button} 
    navigator={navigator} {...route.props} 
> 

これは素晴らしいです:

this.props.navigator.push({ 
component: ContactDetails, 
    props: { 
    title: rowData.name.title, 
    first: rowData.name.first, 
    last: rowData.name.last, 
    } 
}); 
関連する問題