3

我的反应原生应用程序中有这个类别过滤器组件。第一次加载此组件时,它不会滚动到给定的索引项(即 3)。我检查了一下,函数scrollToIndex正在调用。但是在加载屏幕后重新渲染组件时它正在工作。

为什么在第一次加载屏幕时它不向下滚动?

import React, { useCallback, useRef } from 'react'
import { StyleSheet, TouchableOpacity, FlatList, View } from 'react-native'
import { Badge, Text } from 'native-base'
import { connect } from 'react-redux'
import * as categoryActions from '../../Redux/Actions/categoryActions'
import { useFocusEffect } from '@react-navigation/native'

const CategoryFilter = (props) => {
  const flatlistRef = useRef()

  const handleSetSelectedCategoryId = (categoryId) => {
    props.setSelectedCategoryId(categoryId)
  }

  const getItemLayout = (data, index) => ({
    length: 50,
    offset: 50 * index,
    index,
  })

  const scrollToIndex = () => {
    console.log('scroll to index called !')
    let index = 3
    flatlistRef.current.scrollToIndex({ animated: true, index: index })
  }

  useFocusEffect(
    useCallback(() => {
      scrollToIndex()
    }, [])
  )

  const renderItem = ({ item, index }) => {
    return (
      <TouchableOpacity
        key={item._id}
        onPress={() => {
          handleSetSelectedCategoryId(item._id)
        }}
      >
        <Badge
          style={[
            styles.center,
            { margin: 5, flexDirection: 'row' },
            item._id == props.selectedCategoryId
              ? styles.active
              : styles.inactive,
          ]}
        >
          <Text style={{ color: 'white' }}>{item.name}</Text>
        </Badge>
      </TouchableOpacity>
    )
  }

  return (
    <View>
      <FlatList
        data={props.categories}
        renderItem={renderItem}
        keyExtractor={(item) => item._id}
        horizontal={true}
        ref={flatlistRef}
        getItemLayout={getItemLayout}
      />
    </View>
  )
}
....

4

1 回答 1

3

我有一个类似的问题,这些是我的发现:

似乎在 flatlist 使用 getItemLayout 计算完项目大小之前发生了 scrollToIndex 的竞争情况。所以它不会抛出超出范围的错误并认为滚动成功。

一种解决方案是:

setTimeout(() => scrollToIndex(), 500);

然而,这不是一个很好的解决方案,因为不能保证平面列表将在任意给定的 500 毫秒内“准备好”滚动,这意味着我们的延迟调用仍然无法工作。

推荐方式:

在 FlatList 上设置initialScrollIndex我们要滚动到的索引。

数据数组(传递给 FlatList)需要已经有您要查找的索引,否则您将收到超出范围的错误。

您还应该注意(来自文档):

这将禁用“滚动到顶部”优化,该优化使第一个 initialNumToRender 项目始终呈现并立即呈现从该初始索引开始的项目。

更多信息:https ://reactnative.dev/docs/flatlist#initialscrollindex

于 2021-05-08T08:32:08.603 回答