react-native – React Native – ListView滚动到嵌套子参考?
我正在使用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时最明显的评论: 解决方法
好的,我运行了您编辑过的代码并找出了您所缺少的内容. 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}> 当按下可触摸时,它只是平稳地运行和滚动.我在上面的片段中跳过了导入部分. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |