如何通过 ref 访问 React-Native ListView 子组件



如何通过 ref 访问 React-Native ListView 子组件?

class MyComponent extends Component {
  constructor() {
    super();
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      dataSource: ds.cloneWithRows(['row 1', 'row 2', 'row 3', 'row 4', 'row 5', 'row 6']),
    };
  }
  onTap() {
    console.log(this.refs)
    /* After getting touchComponent refs below block of code has to be executed.
    that.refs.touchComponent.measure((ox, oy, width, height, px, py) => {
    this.setState({
       isVisible: true,
       buttonRect: {x: px, y: py, width: width, height: height}
    });
  });
  */
 }
  render() {
    return (
      <ListView ref="listView"
        dataSource={this.state.dataSource}
        renderRow={(rowData) => <TouchableHighlight ref="touchComponent" onPress={this.onTap.bind(this)}><Text>{rowData}</Text></TouchableHighlight>}
      />
    );
  }
}

console.log(this.refs)打印Object {listView: Object}

如何访问TouchableHighlight组件引用?

我浏览了 React Native:ListView 中的 Refs 和 React Native - 从 renderRow 获取 listview 中自定义组件的引用,但我不明白它们是如何做的。

您无法通过在 ListView 中添加 refs 的字符串方式访问 refs,您必须使用回调技术来应用 refs

 <ListView ref="listView"
        dataSource={this.state.dataSource}
        renderRow={(rowData) => <TouchableHighlight ref={(TouchableHighLight) => { this.button = TouchableHighLight; }} onPress={this.onTap.bind(this)}><Text>{rowData}</Text></TouchableHighlight>}
      />

但很可能即使在获得 ref 后,您也无法访问测量方法。要获取 pageX 和 pageY,您可以使用 onPress 传递触摸事件并使用 nativeEvent 获取 pageX 和 pageY,如下所示,您可以使用 measureInWindow 方法获取宽度和高度:

onPress={(event) => this.onTap(event)}

方法定义可以是这样的:-

onTap(evnt) {
  var py=evnt.nativeEvent.pageY
  var px=evnt.nativeEvent.pageX
  console.log(this.refs)
this.button.measureInWindow(x,y,width,height)
  this.setState({
       isVisible: true,
       buttonRect: {x: x, y: y, width: width, height: height}
  });
});
}

您可以尝试这样操作来访问点击的元素:

import React, { Component } from 'react'
import {
  Text,
  ListView,
  TouchableHighlight,
  View,
} from 'react-native';
export default class App extends Component {
  constructor() {
    super();
    this.buildList = this.buildList.bind(this)
    this.onTap = this.onTap.bind(this)
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.rows = []
    this.state = {
      dataSource: ds.cloneWithRows([
        {id: 0, text: 'row 1'},
        {id: 1, text: 'row 2'},
        {id: 2, text: 'row 3'},
        {id: 3, text: 'row 4'},
        {id: 4, text: 'row 5'},
        {id: 5, text: 'row 6'}
      ]),
    };
  }
  onTap(id) {
    console.log(this.rows[id])
 }
  buildList (data) {
    const onRowTap = () => this.onTap(data.id)
    return (
      <TouchableHighlight key={data.id} ref={row => this.rows[data.id] = row} onPress={onRowTap}>
          <Text style={{color: '#000', padding: 20}}>{data.text}</Text>
      </TouchableHighlight>
    )
  }
  render() {
    return (
      <View>
        <ListView style={{marginTop: 50}} ref="listView"
          dataSource={this.state.dataSource}
          renderRow={this.buildList}
        />
      </View>
    );
  }
}

与您发布的链接的概念相同,但也许这种方式更容易理解。不是尝试从类引用中获取行,而是在类范围内创建一个空数组,并在构建列表时用行填充它。然后,您只需将点击时的id传递给press功能,即可获得点击行。他们以同样的方式深入listView引用,因为实际上这些行是ListeView子项,因此您可以引用ListView引用而不是您的Class

引用

最新更新