2017-02-08 10 views
3

ユーザーがイメージをタップしたときにpress()メソッドを実行するReactネイティブコードがあります。 itemIndex propをイベントオブジェクトから取得します。私は、プレスメソッドにブレークポイントを設定し、いくつかの式をウォッチに追加しました。腕時計からは、イベントのターゲット(イベントの発生)が正しいイメージであると判断しました。 itemIndex propも利用できます。処理対象の要素はcurrentTargetです。ウォッチでは「RCTView」と表示され、TouchableOpacityが予想されていました。そのため、TouchableOpacityの下にあるのがビューですか? currentTarget itemIndex propは未定義ですが、なぜですか?どのように私は現在のターゲットから小道具を得ることができますか?Reactネイティブのタッチ可能なイベントから小道具を読む方法currentTarget?

レンダリングされたアイテムごとに追加メソッドを作成しないように、この方法で行いたいと思います。

FYI、 ref={(c) => this._input = c}はループで実行されているため機能しません。 onPress={(e) => this.press(e, i)}は、私が避けようとしている新しい機能を作成します。

ウォッチ

  1. target._currentElement.props.itemIndex:2
  2. target._currentElement.type.displayName: "RCTImageView"
  3. currentTarget._currentElement.props.itemIndex:未定義
  4. currentTarget._currentElement.type.displayName: "RCTView"

    press: function(event){ 
        var currentTarget = ReactNativeComponentTree.getInstanceFromNode(event.currentTarget); 
        var target = ReactNativeComponentTree.getInstanceFromNode(event.target); 
        var currentTargetIndex = currentTarget._currentElement.props.itemIndex; 
        var targetIndex = target._currentElement.props.itemIndex; 
        var url = this.state.data.items[currentTargetIndex].url; 
        Linking.openURL(url).catch(err => console.error('An error occurred', err)); 
    }, 
    
    render: function() { 
    return (
        <ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.galleryView}> 
         { 
          this.state.data.items.map((data, i) => 
           <TouchableOpacity itemIndex={i} key={i} activeOpacity={0.5} onPress={this.press} > 
            <Image itemIndex={i} key={i} source={{uri:data.previewImageUri}} style={styles.galleryImage} /> 
           </TouchableOpacity> 
          ) 
         } 
        </ScrollView> 
    ); 
    } 
    

答えて

1

私は最近、この同じ問題を実際に遭遇しました。私はあなたがこれにアプローチできる2つの異なる方法を見つけました。

press: function(event, index){ 
    var url = this.state.data.items[index].url; 
    Linking.openURL(url).catch(err => console.error('An error occurred', err)); 
}, 

render: function() { 
    return (
    <ScrollView 
     horizontal={true} 
     showsHorizontalScrollIndicator={false} 
     style={styles.galleryView} 
    > 
    { 
     this.state.data.items.map((data, i) => 
     <Images data={data} key={i} index={i} press={this.press} /> 
    ) 
    } 
    </ScrollView> 
    ); 
} 

const Images = (props) => { 
    const imageClicked = (e) => { 
    props.press(e, props.index); 
    } 
    return (
    <TouchableOpacity activeOpacity={0.5} onPress={imageClicked} > 
     <Image source={{uri:props.data.previewImageUri}} style={styles.galleryImage} /> 
    </TouchableOpacity> 
) 
} 
+1

、= {(E)=> this.press(E、I)}たonPressは、私は避けるようにしようとしている新しい関数を作成します。私はプレスハンドラへの参照を渡し、イベントオブジェクトからインデックスを取得したいだけです。 –

+1

はい、そうです。私はそれをやる第2の方法に私の答えを更新しました。基本的には、コンポーネントを作成し、インデックスとプレス関数の両方をプロパティとして渡し、最初のプレス機能を呼び出すが、イベントとインデックスの両方を通過する新しい関数を作成する...私に明確にしたい場合はお知らせくださいさらに。 –

+1

ありがとうMatt!わかった。このソリューションは、Reactネイティブバグの回避策のように見えます。私はもっ​​とエレガントなことを望んでいたのですが、何か間違っていただけでした。私はこのトピックを数日間はハングアップさせ、よりエレガントな、またはこれを実行するための "ネイティブな方法"があるかどうかを確認します。そうでない場合は、https://github.com/facebook/react-native/issuesにリダイレクトします –

0

コールバックに必要な情報をバインドし、それぞれの子に1を割り当てる再作成することを回避する:あなたのプレス関数にインデックスを渡すためにあなたのonPressを変更されたことの簡単な方法は、これはそれを行うための第二の方法であります子のレンダリングごとのコールバック。私の知る限り

class Hello extends React.Component{ 
    state = { names: this.props.names.map((name, i) => { 
     return Object.assign({ 
     onClick: this._onClick.bind(this, i, this.props), 
     }, name) 
    }), 
    }; 

    _onClick(ind, _props, e) { 
    alert('props:' + JSON.stringify(_props)); 
    } 

    render() { 
    const { names } = this.state; 
    return (
     <div> 
     { names.map((name, i) => (
      <div key={i}>Name: <input value={ name.first } onClick={ name.onClick } /></div> 
     ))} 
     </div> 
)} 
} 

ReactDOM.render(
    <Hello names={[{first:'aaa'},{first:'bbb'},{first:'ccc'}]}/>, 
    document.getElementById('container') 
); 

JS Fiddle

関連する問題