cri*_*ian 7 animation reference undefined react-native react-native-flatlist
我面临着 React Native 中似乎长期存在的问题。
我正在使用带有 RN 版本 0.59 的 Expo SDK35。由于代码库较大,我尚未更新到 Expo SDK36 / RN 0.60,但如果这可以弥补我的问题的解决方案,我可以更新。
我有一个Animated.View有FlatList子组件的组件,并且我无法使用scrollToIndex()FlatList 引用上应该提供的静态方法(特别是)。请参阅下一个示例代码:
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>
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用Animated.FlatList它,但仍然抛出与上面的代码示例中相同的错误。
我还尝试findNodeHandle()在接收到的参数上使用 React Native 的实用函数flatListRef,但它返回null.
我发现过去在 Stack Overflow 上多次发布过同样的问题,大多数都没有答案,或者对我不起作用。这些帖子也有点旧(一年左右),这就是为什么我针对同一问题再次发帖。
有人设法找到此问题的解决方案/解决方法吗?
当我玩代码时,我尝试使用ScrollView组件而不是FlatList- 并且该scrollTo方法有效!
更改仅针对 FlatList - ScrollView 特定道具(因此,对于 ScrollLView 来说,它将是子级而不是data={[...]}和renderItem={()=>{ ... }}等),以及scrollToIndexcomponentDidMount 中的方法被替换为scrollTo。
该类的 render 方法(带有 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>
Run Code Online (Sandbox Code Playgroud)
请注意,ScrollView 没有scrollToIndex()方法,因此您必须手动跟踪子位置,并且也许需要实现您自己的scrollToIndex 方法。
我不会将此作为我问题的答案,因为根本问题仍然存在。但作为一种解决方法,也许你可以接受它,然后就到此为止......
this.myRef = React.createRef();
this.myRef.current.doSomething(); // note the use of 'current'
Run Code Online (Sandbox Code Playgroud)
虽然我尝试的想法是正确的,但我原来的帖子中的错误似乎非常愚蠢。在我看来,文档不清楚(可能......)。反正...
React.createRef返回一个带有一些字段的对象,所有这些字段对开发人员来说都是无用的(由 React 在后面使用) - 除了一个:current。该属性保存对 ref 所附加到的底层组件的当前引用。主要 ref 对象无法用于我在上面的原始问题中的目的。
相反,这就是我应该正确使用 ref 的方式:
this.myRef.current.scrollToIndex(...)
Run Code Online (Sandbox Code Playgroud)
myRef如果组件尚未安装、稍后已卸载,或者由于某种原因无法将引用附加到它,则主对象和字段都将是current。null正如您可能知道的(或稍后发现的),null.something会抛出错误。因此,为了避免它:
if ((this.myRef !== null) && (this.myRef.current !== null)){
this.myRef.current.scrollToIndex(...);
}
Run Code Online (Sandbox Code Playgroud)
如果您尝试将未定义的值作为函数调用 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(...);
}
}
Run Code Online (Sandbox Code Playgroud)
或者
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这对学习在 React 中使用 ref 的其他人有用。干杯:)
| 归档时间: |
|
| 查看次数: |
13221 次 |
| 最近记录: |