You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次渲染时渲染外部函数数据?下拉菜单数据获取报错求助

问题分析与解决方案

1. 类型错误原因

fetch_libraries是异步函数,直接调用会返回Promise对象,但Dropdown组件的data属性需要的是数组类型,这就是你看到类型报错的核心原因。

2. 首次渲染为空的修复

用useState维护下拉菜单数据,useEffect触发异步请求,同时添加加载状态避免空数据展示,还要完善异步请求的错误处理逻辑。


修改后的代码

第一步:优化fetch_libraries.js(确保返回类型稳定)

import { getItemFor } from './async_store';
import { supabase } from './supabase';

export default async function libraries_fetch() {
  try {
    const libraries = [];
    const email = await getItemFor("email");
    
    if (!email) {
      console.error("用户邮箱未获取到");
      return libraries;
    }

    const { data, error } = await supabase
      .storage
      .from('pdfs')
      .list(`${email}/books`);
    
    if (error) throw error;
    
    if (data) {
      data.forEach((item, index) => {
        libraries.push({ label: item.name, value: index.toString() });
      });
    }
    
    return libraries;
  } catch (err) {
    console.error("获取库列表失败:", err);
    return []; // 始终返回数组,避免undefined导致类型问题
  }
};

第二步:修改主library.tsx页面

// Expo 
import Ionicons from '@expo/vector-icons/Ionicons';
import { Stack } from 'expo-router';
import { Dropdown } from 'react-native-element-dropdown';

// App Backend
import { styles } from '../../assets/stylers';
import Colors from '@/constants/Colors';
import fetch_libraries from '../backend/fetch_libraries';

// React
import { View, useEffect, useState, Text } from 'react-native';

export default function library() {
  // 初始化状态:空数组作为默认值,同时指定TypeScript类型
  const [libraryData, setLibraryData] = useState<{ label: string; value: string }[]>([]);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    // 封装异步请求逻辑,避免直接在useEffect中写async函数
    const loadLibraries = async () => {
      try {
        const data = await fetch_libraries();
        setLibraryData(data);
      } catch (err) {
        console.error("加载库数据失败:", err);
      } finally {
        setIsLoading(false);
      }
    };

    loadLibraries();
  }, []); // 空依赖数组确保只在组件挂载时执行一次

  return (
    <View>
      <Stack.Screen 
        options={{
          headerStyle: styles.HeaderStyle, 
          headerTitleStyle: styles.HeaderTextStyle, 
          headerRight: () => 
            isLoading ? (
              // 加载状态展示提示,可替换为加载指示器组件
              <View style={{paddingRight: 15}}>
                <Text>加载中...</Text>
              </View>
            ) : (
              <Dropdown
                style={styles.libraryDropDownScroll}
                itemContainerStyle={styles.libraryDropDownItem}
                containerStyle={styles.libraryDropDownContainer}
                data={libraryData} // 使用状态中的数组,满足类型要求
                labelField="label"
                valueField="value"
                placeholder='Main'
                onChange={item => {}}
                renderRightIcon={() => (
                  <Ionicons
                    name="arrow-down" 
                    size={20} 
                    color={Colors.black} 
                    style={styles.closeIconStyle}
                  />
                )}
              />
            )
        }}
      />
    </View>
  );
};

关键要点
  • 异步逻辑规范:必须在useEffect中触发异步请求,不能直接在组件顶层调用异步函数,否则会导致重复渲染或状态更新异常。
  • 类型安全保障:让fetch_libraries始终返回数组类型,同时给useState指定明确的TypeScript类型,彻底消除类型报错。
  • 用户体验优化:添加isLoading状态,在请求完成前展示加载提示,避免下拉菜单显示空数据。

内容的提问来源于stack exchange,提问作者Anirudh Kuppili

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 21:25:09