加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

react-native – React Native – ListView滚动到嵌套子参考?

发布时间:2020-12-15 20:31:45 所属栏目:百科 来源:网络整理
导读:我正在使用ListView显示评论列表以及可能的子评论(如果它们存在于评论中).我试图通过它的参考滚动到一个特定的子评论,但我无法让它工作.我使用了3个组件(在下面简化)来实现这个目的: 1.评论 import React,{ Component } from 'react'import { TouchableOpac
我正在使用ListView显示评论列表以及可能的子评论(如果它们存在于评论中).我试图通过它的参考滚动到一个特定的子评论,但我无法让它工作.我使用了3个组件(在下面简化)来实现这个目的:

1.评论

import React,{ Component } from 'react'
import { TouchableOpacity,ListView,View,Text } from 'react-native'
import CommentRow from './commentRow'

const ds = new ListView.DataSource({ rowHasChanged: ( r1,r2 ) => r1.id !== r2.id });
const commentsDataSource = [
  {id: '1',body: 'comment 1'},{id: '2',body: 'comment 2'},{id: '3',body: 'comment 3'},{id: '4',body: 'comment 4'},{id: '5',body: 'comment 5'},{id: '6',body: 'comment 6'},{id: '7',body: 'comment 7'},{id: '8',body: 'comment 8'},{id: '9',body: 'comment 9'},{id: '10',body: 'comment 10'},{id: '11',body: 'comment 11'},{id: '12',body: 'comment 12',hasSubComments: true},{id: '13',body: 'comment 13'},{id: '14',body: 'comment 14'},{id: '15',body: 'comment 15'},{id: '16',body: 'comment 16'},{id: '17',body: 'comment 17'},{id: '18',body: 'comment 18'},{id: '19',body: 'comment 19'},{id: '20',body: 'comment 20'}
];

export default class Comments extends Component {
    constructor(props) {
      super(props);

      this.state = {
        dataSource: ds.cloneWithRows(commentsDataSource)
      };
    }

    scrollToSubCommentRef(ref) {
      this.rowz[ref].measure((ox,oy,width,height,px,py) => {
        const offsetY = oy;
        this.refs.mainListView.scrollTo({ y: offsetY })
      });
    }

    render() {
      return (
        <View>
            <TouchableOpacity style={{backgroundColor: 'red',padding: 50}}
                              onPress={() => this.scrollToSubCommentRef('subComment_10')}>
                <Text>Scroll to subComment_10!</Text>
            </TouchableOpacity>

            <ListView ref="mainListView"
                      renderRow={comment => <CommentRow comment={comment} />}
                      dataSource={this.state.dataSource}
                      enableEmptySections={true} />
        </View>
      )
    }
}

2.评论路

import React,{ Component } from 'react';
import { View } from 'react-native'
import CommentListItem from './commentListItem'

export default class CommentRow extends Component {
    render() {
      const comment = this.props.comment;

      return (
        <View key={`comment_${comment.id}`} style={{overflow: 'hidden'}}>
          <CommentListItem comment={comment} />
        </View>
      )
    }
}

3. CommentListItem

import React,{ Component } from 'react'
import { View,Text } from 'react-native'

const subComments = [
  {id: '1',body: 'subcomment 1'},body: 'subcomment 2'},body: 'subcomment 3'},body: 'subcomment 4'},body: 'subcomment 5'},body: 'subcomment 6'},body: 'subcomment 7'},body: 'subcomment 8'},body: 'subcomment 9'},body: 'subcomment 10'},body: 'subcomment 11'},body: 'subcomment 12'},body: 'subcomment 13'},body: 'subcomment 14'},body: 'subcomment 15'},body: 'subcomment 16'},body: 'subcomment 17'},body: 'subcomment 18'},body: 'subcomment 19'},body: 'subcomment 20'},{id: '21',body: 'subcomment 21'},{id: '22',body: 'subcomment 22'},{id: '23',body: 'subcomment 23'},{id: '24',body: 'subcomment 24'},{id: '25',body: 'subcomment 25'},{id: '26',body: 'subcomment 26'},{id: '27',body: 'subcomment 27'},{id: '28',body: 'subcomment 28'},{id: '29',body: 'subcomment 29'},{id: '30',body: 'subcomment 30'},{id: '31',body: 'subcomment 31'},{id: '32',body: 'subcomment 32'},{id: '33',body: 'subcomment 33'},{id: '34',body: 'subcomment 34'},{id: '35',body: 'subcomment 35'},{id: '36',body: 'subcomment 36'},{id: '37',body: 'subcomment 37'},{id: '38',body: 'subcomment 38'},{id: '39',body: 'subcomment 39'},{id: '40',body: 'subcomment 40'},{id: '41',body: 'subcomment 41'},{id: '42',body: 'subcomment 42'},{id: '43',body: 'subcomment 43'},{id: '44',body: 'subcomment 44'},{id: '45',body: 'subcomment 45'},{id: '46',body: 'subcomment 46'},{id: '47',body: 'subcomment 47'},{id: '48',body: 'subcomment 48'},{id: '49',body: 'subcomment 49'},{id: '50',body: 'subcomment 50'},{id: '51',body: 'subcomment 51'},{id: '52',body: 'subcomment 52'},{id: '53',body: 'subcomment 53'},{id: '54',body: 'subcomment 54'},{id: '55',body: 'subcomment 55'},{id: '56',body: 'subcomment 56'},{id: '57',body: 'subcomment 57'},{id: '58',body: 'subcomment 58'},{id: '59',body: 'subcomment 59'},{id: '60',body: 'subcomment 60'},{id: '61',body: 'subcomment 61'},{id: '62',body: 'subcomment 62'},{id: '63',body: 'subcomment 63'},{id: '64',body: 'subcomment 64'},{id: '65',body: 'subcomment 65'},{id: '66',body: 'subcomment 66'},{id: '67',body: 'subcomment 67'},{id: '68',body: 'subcomment 68'},{id: '69',body: 'subcomment 69'},{id: '70',body: 'subcomment 70'}
];

export default class CommentListItem extends Component {
  rowz = []; // to hold subComment refs for scroll access

  subCommentsList = () => {
    return subComments.map((subComment,i) => {
      return (
        <View ref={i => this.rowz["subComment_"+subComment.id] = i} key={"subComment_"+subComment.id}>
          <Text>{subComment.body}</Text>
        </View>
      );
    });
  }

  render() {
    const comment = this.props.comment;

    return (
      <View>
        <Text>{comment.body}</Text>
        {comment.hasSubComments && this.subCommentsList()}
      </View>
    )
  }
}

在父组件#1中,我试图通过其subComment_10的ref滚动到一个subComment,但是measure给出了一个未定义的错误.我理解this.rowz在#3中不存在于#3中,其中subComments map迭代每个subComment并将其分配给rowz数组(我刚刚意识到它没有因为某种原因将subComment_idhere分配给rowz数组).

那么我们如何在#3映射中修复ref赋值问题,以便rowz数组获取所有subComment引用的列表,以便我们可以滚动到它们?我们如何在#1中使用this.scrollToSubCommentRef(‘subComment_10’)获取TouchableOpacity以将mainListView滚动到subComment_10?

UPDATE

使用提供的解决方案,ref成功传递给rowz数组,但正如您将注意到的,它不会滚动到subComment_10,而是滚动到注释10的底部.它应滚动到subComment_10的顶部以便它是点击TouchableHighlight时最明显的评论:

enter image description here

解决方法

好的,我运行了您编辑过的代码并找出了您所缺少的内容. refz数组是在CommentListItem类中本地创建的,因此您无法从父类访问它.但是,由于您将从父类进行所有导航,将prop数组传递到最底层,并填充它将是一种更好的方法.这样你就不会得到this.rowz是未定义的错误并按预期运行你的代码.

export default class Comments extends Component {
constructor(props) {
  super(props);
  this.rowz = []
  this.state = {
    dataSource: ds.cloneWithRows(commentsDataSource)
  };
}

scrollToSubCommentRef(ref) {
  this.rowz[ref].measure((ox,py) => {
    const offsetY = oy;
    this.refs.mainListView.scrollTo({ y: offsetY })
  });
}

render() {
  return (
    <View>
        <TouchableOpacity style={{backgroundColor: 'red',padding: 50}}
                          onPress={() => this.scrollToSubCommentRef('subComment_10')}>
            <Text>Scroll to subComment_10!</Text>
        </TouchableOpacity>

        <ListView ref="mainListView"
                  renderRow={comment => <CommentRow refArr={this.rowz} comment={comment} />}
                  dataSource={this.state.dataSource}
                  enableEmptySections={true} />
    </View>
  )
}
}

在Comments类中,我们将在构造函数中创建的数组(this.rowz)传递给CommentsRow类?

<CommentRow refArr={this.rowz} comment={comment} />

在CommentRow类中,我们将只传递父类中的内容,

export default class CommentRow extends Component {
    render() {
      const comment = this.props.comment;

      return (
        <View key={`comment_${comment.id}`} style={{overflow: 'hidden'}}>
          <CommentListItem refArr={this.props.refArr} comment={comment} />
        </View>
      )
    }
}

就在这儿:

<CommentListItem refArr={this.props.refArr} comment={comment} />

最后,在CommentListItem类中,为了填充我们的数组,我们可以简单地调用this.props.refArr.push()

export default class CommentListItem extends Component {
  rowz = []; // to hold subComment refs for scroll access

  subCommentsList = () => {
    return subComments.map((subComment,i) => {
      return (
        <View ref={i => this.props.refArr["subComment_"+subComment.id] = i} key={"subComment_"+subComment.id}>
          <Text>{subComment.body}</Text>
        </View>
      );
    });
  }

  render() {
    const comment = this.props.comment;

    return (
      <View>
        <Text>{comment.body}</Text>
        {comment.hasSubComments && this.subCommentsList()}
      </View>
    )
  }
}

你可能会在这里看得更清楚:

<View ref={i => this.props.refArr["subComment_"+subComment.id] = i} key={"subComment_"+subComment.id}>

当按下可触摸时,它只是平稳地运行和滚动.我在上面的片段中跳过了导入部分.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读