【问题标题】:React Native FlatList - when isLoading not rendering footerReact Native FlatList - 当isLoading不呈现页脚时
【发布时间】:2021-08-31 22:08:10
【问题描述】:

到达列表末尾时,我的 react native flatlist 出现问题。

我需要的行为是典型的:到达结束时获取数据库,在操作期间在页脚处显示加载指示器。

问题是,由于某些原因,没有显示加载指示器。

这是我的 FlatList 组件:

    ...

    const renderFooter = () => {
        if (!props.isLoading) return null;

        return (
          <View style={{ paddingVertical: 35 }}>
             <Loading type="ios" size={30} color={colors.primary} />
          </View>
        );
    };

    return (
      <FlatList
        ref={ref}
        data={data}
        keyExtractor={keyExtractor}
        renderItem={renderItem}
        windowSize={5}
        maxToRenderPerBatch={5}
        updateCellsBatchingPeriod={50}
        removeClippedSubviews={false}
        initialNumToRender={initialNumToRender}
        ListFooterComponent={renderFooter}
        ListEmptyComponent={ListEmptyComponent}
        onEndReached={onEndReached}
        onEndReachedThreshold={0.5}
        showsVerticalScrollIndicator={false}
        style={{ flexGrow: 1 }}
        contentContainerStyle={{ flexGrow: 1 }}
      />
    );

这就是我获取数据库的方式:

const [items, setItems] = useState([]);
const [isGettingMoreOldItems, setIsGettingMoreOldItems] = useState(true);

const fetchItems = async (old = true) => {
   ...
   const newItems = await db.getItems();
   setItems(old ? [...items, ...newItems] : [...newItems, ...items]);
   ...
}

const getMoreOldItems = async () => {
   setIsGettingMoreOldItems(true);
   await fetchItems(); // <--------- I AM AWAITING!
   setIsGettingMoreOldItems(false);
}

 ...

return <MyList ... isLoading={isGettingMoreOldItems} onEndReached={getMoreOldItems} ... />

为什么当到达列表末尾并且应用程序开始获取数据库时,我没有看到加载指示器?我该如何解决这个问题?

注意:获取操作持续 2 秒(大约)

好奇心

如果我这样做:

const getMoreOldItems = async () => {
   setIsGettingMoreOldItems(true);
   await fetchItems(); // <--------- I AM AWAITING!

   setTimeout(() => {
      setIsGettingMoreOldItems(false);
   }, 1000);
}

我可以看到页脚。但似乎有点棘手,不清楚...

【问题讨论】:

标签: javascript css reactjs react-native


【解决方案1】:

首先是里面的代码:

const getMoreOldItems = async () => {
   setIsGettingMoreOldItems(true);
   await fetchItems(); // <--------- I AM AWAITING!
   setIsGettingMoreOldItems(false);
}

应该是这样的:

const getMoreOldItems = async () => {
   await setIsGettingMoreOldItems(true);
   await fetchItems(); // <--------- I AM AWAITING!
   await setIsGettingMoreOldItems(false);
}

第二件事,请永远记住所有 JS 都是异步 D:.

如果上述方法不起作用,也可以使用匿名函数:

(async () => {
await setIsGettingMoreOldItems(true);
await fetchItems(); // <--------- I AM AWAITING!
await setIsGettingMoreOldItems(false);
})();

更新:

await 仅在您将其与 Promise 一起使用时才有用,但 requests(在您的情况下为 fetch)不会返回 Promise。它根本没有 return 语句,所以它隐式返回 undefined。

因此,只需在每次提取后执行以下操作:

let data = await response.json(); // or similar upon your needs - blob, etc

在你的情况下,它会是这样的:

let data = await newItems.json();

【讨论】:

  • 不可能等待 useState 设置器。此外,它会引发警告:“await 对此表达式的类型没有影响。”
  • 此外,原始代码的异步/等待也有效。错误来自意想不到的地方。
  • 但是,状态更新是异步的,但不能作为 Promise 处理。相反,正确的方法是使用自定义钩子。
  • 因为您的 fetch 没有响应。查看更新的答案。
  • 不工作的人。不必将 await 的结果保存在变量中。
猜你喜欢
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
  • 2020-08-07
  • 2021-12-17
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多