Как читать реквизиты из события React Native touchable currentTarget?

У меня есть следующий код React Native, который запускает метод press(), когда пользователь нажимает на изображение. Я хочу получить реквизит itemIndex от объекта события. Я установил точку останова в методе печати и добавил несколько выражений в Watch. Из Часов я определил, что целью (источником события) события является изображение, которое является правильным. ItemIndex реквизит также доступна. Элемент, который обрабатывается, является currentTarget, Watch видит его как "RCTView", и я ожидал TouchableOpacity, так что, может быть, под TouchableOpacity это View? Опора currentTarget itemIndex не определена, почему? Как я могу получить реквизит от 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>
    );
    }
    

2 ответа

Решение

Я на самом деле недавно столкнулся с этой же проблемой, я нашел два разных способа решения этой проблемы. Самый простой способ сделать это изменить ваш onPress чтобы передать индекс функции печати, это 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>
  )
}

Вы можете сделать свой обработчик событий каррированной функцией, которая принимает дополнительные параметры.

 //Curried function for onPress event handler
  handleOnPress = (someId, someProp) => event => {
    //USE someProp ABOVE TO ACCESS PASSED PROP, WHICH WOULD BE undefined IN THIS CASE
    //Use event parameter above to access event object if you need
    console.log(someProp)

    this.setState({
      touchedId: someId
    })
  }

Ознакомьтесь с рабочей закуской ниже

https://snack.expo.io/@prashand/accessing-props-from-react-native-touch-event

Привязка необходимой информации к обратному вызову и назначение ее каждому дочернему элементу позволяет избежать повторного вызова обратного вызова при каждом отображении дочерних элементов.

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

Другие вопросы по тегам