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

React Native中useState状态更新失败及数据访问报错求助

React Native + Sanity 数据渲染错误排查与修复

问题概述

开发React Native应用时使用Sanity作为内容管理系统,API已返回正确的服务数据,但调用setdata后services状态更新异常,FlatList渲染时出现TypeError: Cannot read property 'name' of undefined错误,尝试使用useEffect未解决问题。

错误原因分析

代码存在多个关键问题:

  • FlatList renderItem参数错误:renderItem回调的单个数据项是item而非data,用{data}解构会导致无法获取有效数据,直接引发data为undefined的错误。
  • renderItem函数未返回JSX:renderpage内的JSX没有用return包裹,函数默认返回undefined,FlatList无法正常渲染。
  • useEffect依赖错误:将services作为依赖会触发无限循环,且setState是异步操作,console.log(services)无法即时看到更新结果。
  • location字段处理不当:API返回的location是geopoint对象,直接渲染会引发错误。
  • 不存在的url字段:API返回数据中无url字段,Image组件调用data.url会报错。
  • FlatList缺少keyExtractor:未指定唯一key可能导致渲染警告或性能问题。

修复步骤

  1. 修正renderItem参数与返回值:将参数改为{item},并用return包裹JSX:
const renderpage = ({ item }) => {
  return (
    <View style={{ marginVertical: 10, padding: 10, borderWidth: 1, borderColor: '#eee', borderRadius: 8 }}>
      <Text className="font-bold text-lg">{item.name}</Text>  
      <Text className="font-bold">位置: {item.location.lat}, {item.location.lng}</Text>
      <Text>工作时长: {item.workhour}</Text>
      {/* 其他元素 */}
    </View>
  )
}
  1. 调整useEffect依赖:改为空数组,确保仅在组件挂载时调用一次数据获取:
useEffect(() => {
  fetchdata();
}, []);
  1. 处理location字段:提取经纬度展示,避免直接渲染对象:
<Text className="font-bold">位置: {item.location.lat}, {item.location.lng}</Text>
  1. 移除或替换不存在的url字段:若需显示图片,需在Sanity查询中添加图片字段(如image{url}),否则暂时注释Image组件或使用占位图:
{/* <Image source={{ uri: 'https://via.placeholder.com/100' }} style={{ height: 96, width: 96, borderRadius: 48, marginTop: 8 }} /> */}
  1. 给FlatList添加keyExtractor:用唯一字段标识列表项,建议在Sanity查询中加入_id:
<FlatList 
  data={services}
  renderItem={renderpage}
  keyExtractor={(item) => item._id}
/>

完整修复代码

import { StyleSheet, Text, View, Image, SafeAreaView } from 'react-native'
import React, { useEffect, useState } from 'react'
import { Pressable } from 'react-native';
import { FlatList } from 'react-native-gesture-handler';
import client from '../sanity';

const Jobcard = () => {
  const [services, setdata] = useState([]);

  useEffect(() => {
    fetchdata();
  }, []);

  // 监听services状态变化,查看更新后的数据
  useEffect(() => {
    console.log('当前services:', services);
  }, [services]);

  const fetchdata = async () => {
    try {
      // 加入_id作为唯一标识,方便keyExtractor使用
      const query = `*[_type == "service"]{_id, accepter{_ref}, requester{_ref}, datetime, name, location, workhour}`;
      const response = await client.fetch(query);
      console.log('API返回数据:', response);
      setdata(response);
    } catch (error) {
      console.log('数据获取错误:', error);
    }
  }

  const requestService = () => {
    console.log("service requested");
  }

  const renderpage = ({ item }) => {
    return (
      <View style={{ marginVertical: 10, padding: 10, borderWidth: 1, borderColor: '#eee', borderRadius: 8 }}>
        <Text className="font-bold text-lg">{item.name}</Text>  
        <Text className="font-bold">位置: {item.location.lat}, {item.location.lng}</Text>
        <Text>工作时长: {item.workhour}</Text>
        <View className="flex-row justify-center mt-3 space-x-6 items-center">
          <View className="bg-green-500 px-2 py-2 rounded-md">
            <Pressable android_ripple={{ color: "gray" }} onPress={requestService}>
              <Text className="text-center text-white">立即请求</Text>
            </Pressable>
          </View>
        </View>
        {/* 若需图片,请在Sanity查询中添加image字段,例如accepter->{image{url}},再替换为item.accepter.image.url */}
        {/* <Image source={{ uri: 'https://via.placeholder.com/100' }} style={{ height: 96, width: 96, borderRadius: 48, marginTop: 8 }} /> */}
      </View>
    )
  }

  return (
    <SafeAreaView style={{ flex: 1, paddingHorizontal: 10 }}>
      <FlatList 
        data={services}
        renderItem={renderpage}
        keyExtractor={(item) => item._id}
      />
    </SafeAreaView>
  )
}

export default Jobcard

const styles = StyleSheet.create({})

额外说明

  • 确保Sanity客户端配置正确,能正常获取数据。
  • 若需显示关联文档的图片(如服务提供者头像),需在Sanity查询中添加引用字段的扩展查询,例如accepter->{image{url}}。

内容的提问来源于stack exchange,提问作者Manoj Bhat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:55:00