Как читать реквизиты из события 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)}
создает новую функцию, которую я пытаюсь избежать.
Часы
- target._currentElement.props.itemIndex: 2
- target._currentElement.type.displayName: "RCTImageView"
- currentTarget._currentElement.props.itemIndex: не определено
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')
);