我面对的似乎是一个长期存在的问题,在反应本土。
我使用的是RN版本0.59的世博会SDK35。我还没有更新到世博会SDK36 /RN0.60,因为有大量的代码库,但我可以更新,如果这弥补了我的问题的解决方案。
我有一个Animated.View组件,它有一个FlatList子组件,我无法使用应该在FlatList引用上可用的静态方法(特别是scrollToIndex())。请参阅下一个示例代码:
class Example extends React.Component{
constructor(props){
super(props);
this.myRef = null;
}
componentDidUpdate = () => {
/*
somewhere in code outside this class, a re-render triggers
and passes new props to this class.
I do have props change detection, and some more other code,
but I have removed it in order to minimize the code example here
*/
// This call throws:
// TypeError: undefined is not a function (near '...this._scrollRef.scrollTo...')
this.myRef.scrollToIndex({
animated: true,
index: 1,
viewOffset: 0,
viewPosition: 0.5
});
// Other suggested solution from SO
// This also throws:
// TypeError: _this.myRef.getNode is not a function. (In '_this.myRef.getNode()', '_this.myRef.getNode' is undefined)
this.myRef.getNode().scrollToIndex({
animated: true,
index: 1,
viewOffset: 0,
viewPosition: 0.5
});
}
render = () => <Animated.View style={{ /* ... some animated props */ }}>
<FlatList ref={(flatListRef) => { this.myRef = flatListRef; }}
// more FlatList related props
/>
</Animated.View>
}我尝试使用Animated.FlatList,但仍然抛出与上面的代码示例相同的错误。
我还尝试在接收到的findNodeHandle()参数上使用本机的flatListRef实用程序函数,但它返回null。
我发现相同的问题在过去多次张贴在堆栈溢出,大多数没有答案,或对我不起作用。这些帖子也有点老(一年左右),这就是为什么我再次为同样的问题张贴。
有人能找到解决这个问题的办法吗?
编辑:可能的解决办法
当我在处理代码时,我尝试使用ScrollView组件而不是FlatList --而scrollTo方法可以工作!
这些变化只发生在FlatList - ScrollView特定的道具上(因此,对于ScrolLView,它将是childs而不是data={[...]}和renderItem={()=>{ ... }}等),以及componentDidMount中的scrollToIndex方法,后者被scrollTo所取代。
类的呈现方法(带有ScrollView )现在看起来如下所示:
render = () => <Animated.View style={{ /* ... some animated props */ }}>
<ScrollView ref={(flatListRef) => { this.myRef = flatListRef; }}>
{/*
this.renderItem is almost the same as the
renderItem method used on the FlatList
*/}
{ this.state.dataArray.map(this.renderItem) }
</ScrollView>
</Animated.View>请注意,ScrollView没有scrollToIndex()方法,因此您将不得不手动跟踪子位置,并可能实现自己的scrollToIndex方法。
我并不是回答我的问题,因为根本的问题仍然存在。但作为一种解决办法,也许你可以和它一起结束.
发布于 2020-10-06 19:15:29
TL;DR;
this.myRef = React.createRef();
this.myRef.current.doSomething(); // note the use of 'current'长篇版本:
虽然我的尝试背后的想法是正确的,但我原来的帖子中的错误似乎相当愚蠢。为了我的辩护,医生们还不清楚(可能.)。不管怎样..。
React.createRef返回一个有几个字段的对象,所有这些字段对开发人员毫无用处(后面的React使用)--除了一个:current。此支柱保存对ref附加到的基础组件的当前引用。主ref对象不能用于我原来的问题中的目的。
相反,我应该这样正确地使用ref:
this.myRef.current.scrollToIndex(...)等等,别撞车
主myRef对象和current字段都将是null,如果组件尚未挂载,以后任何时候都已卸载,或者由于某种原因无法将ref附加到它。您可能知道(或者稍后会发现),null.something会抛出一个错误。因此,为了避免这种情况:
if ((this.myRef !== null) && (this.myRef.current !== null)){
this.myRef.current.scrollToIndex(...);
}额外保险
如果尝试将未定义的值作为ref上字段上的函数调用,则代码将崩溃。如果错误地在多个组件上重用相同的引用,或者附加它的组件没有该方法(即View没有scrollTo方法),就会发生这种情况。要解决这个问题,您有两个解决方案:
// I find this to be the most elegant solution
if ((this.myRef !== null) && (this.myRef.current !== null)) {
if (typeof this.myRef.current.scrollToIndex === "function") {
this.myRef.current.scrollToIndex(...);
}
}或
if ((this.myRef !== null) && (this.myRef.current !== null)) {
if (typeof this.myRef.current.scrollToIndex === "function") {
try {
this.myRef.current.scrollToIndex(...);
} catch (error) {
console.warn("Something went wrong", error);
}
}
}我希望这对其他学习使用参考文献的人有帮助。干杯:)
发布于 2019-12-13 06:56:46
与Animated.ScrollView
<ScrollView ref={ (ref) => (this.MyRef=ref) } />
使用this.myRef.getNode().scrollToIndex的
scrollToIndex不幸的是,Animated.FlatList目前没有工作.
与FlatList
<FlatList ref={ this.flatListRef } />
constructor(props) {
super(props);
this.flatListRef = React.createRef();
}使用this.flatListRef.current.scrollToIndex的
scrollToIndex还要确保将代码包装在if语句中,如下所示:
if (this.myRef.getNode()) { this.flatListRef.getNode().scrollToIndex(); }发布于 2019-12-13 14:17:07
不知道这是否对你有帮助..。它滚动到列表中的特定项目:
/*Example to Scroll to a specific position in scrollview*/
import React, { Component } from 'react';
//import react in our project
import {
View,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
Image,
TextInput,
} from 'react-native';
//import all the components we needed
export default class App extends Component {
constructor() {
super();
//Array of Item to add in Scrollview
this.items = [
'zero',
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'ten ',
'eleven',
'twelve',
'thirteen',
'fourteen',
'fifteen',
'sixteen',
'seventeen',
'eighteen',
'nineteen',
'twenty ',
'twenty-one',
'twenty-two',
'twenty-three',
'twenty-four',
'twenty-five',
'twenty-six',
'twenty-seven',
'twenty-eight',
'twenty-nine',
'thirty',
'thirty-one',
'thirty-two',
'thirty-three',
'thirty-four',
'thirty-five',
'thirty-six',
'thirty-seven',
'thirty-eight',
'thirty-nine',
'forty',
];
//Blank array to store the location of each item
this.arr = [];
this.state = { dynamicIndex: 0 };
}
downButtonHandler = () => {
if (this.arr.length >= this.state.dynamicIndex) {
// To Scroll to the index 5 element
this.scrollview_ref.scrollTo({
x: 0,
y: this.arr[this.state.dynamicIndex],
animated: true,
});
} else {
alert('Out of Max Index');
}
};
render() {
return (
<View style={styles.container}>
<View
style={{
flexDirection: 'row',
backgroundColor: '#1e73be',
padding: 5,
}}>
<TextInput
value={String(this.state.dynamicIndex)}
numericvalue
keyboardType={'numeric'}
onChangeText={dynamicIndex => this.setState({ dynamicIndex })}
placeholder={'Enter the index to scroll'}
style={{ flex: 1, backgroundColor: 'white', padding: 10 }}
/>
<TouchableOpacity
activeOpacity={0.5}
onPress={this.downButtonHandler}
style={{ padding: 15, backgroundColor: '#f4801e' }}>
<Text style={{ color: '#fff' }}>Go to Index</Text>
</TouchableOpacity>
</View>
<ScrollView
ref={ref => {
this.scrollview_ref = ref;
}}>
{/*Loop of JS which is like foreach loop*/}
{this.items.map((item, key) => (
//key is the index of the array
//item is the single item of the array
<View
key={key}
style={styles.item}
onLayout={event => {
const layout = event.nativeEvent.layout;
this.arr[key] = layout.y;
console.log('height:', layout.height);
console.log('width:', layout.width);
console.log('x:', layout.x);
console.log('y:', layout.y);
}}>
<Text style={styles.text}>
{key}. {item}
</Text>
<View style={styles.separator} />
</View>
))}
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 30,
},
separator: {
height: 1,
backgroundColor: '#707080',
width: '100%',
},
text: {
fontSize: 16,
color: '#606070',
padding: 10,
},
});如果我完全错了,告诉我.
https://stackoverflow.com/questions/59317474
复制相似问题