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

React Native使用useEffect获取数据时多次渲染及数据未定义问题

问题原因

  • 命名冲突问题:你自定义的请求函数命名为fetch,和RN/浏览器环境下的全局网络请求方法fetch重名。函数内部调用fetch()时,作用域优先读取你自定义的这个函数,而非全局请求方法,相当于递归调用自身,自然拿不到接口返回的data,还会触发报错。
  • 循环渲染问题:如果你将fetch函数放入了useEffect的依赖数组,就会触发循环:组件每次渲染都会生成新的fetch函数实例,触发useEffect重新执行,接口请求完成后修改state又导致组件重渲染,往复循环。你当前代码里useEffect是空依赖数组,理论上不会循环,大概率是你之前调试时修改过依赖配置才出现这个问题。

修复方案

  1. 给自定义请求函数改名,避免和全局方法冲突
  2. 若需要把请求函数放在useEffect外,可配合useCallback包裹稳定函数实例,避免不必要的重渲染触发
  3. 空依赖数组的useEffect本身就等效于class组件的componentDidMount,仅会在组件首次挂载后执行一次,不用额外修改

修复后的完整代码

import { StatusBar } from 'expo-status-bar';
import React ,{useState,useEffect, useCallback} from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  const [loading, setLoading] = useState(true);
  const [users, setUsers] = useState([]);

  // 改名+useCallback包裹稳定实例
  const fetchCoffeeData = useCallback(async () => {
    try{
      // 调用的是全局fetch,不会冲突
      const res = await fetch("https://api.sampleapis.com/coffee/hot", {method: 'GET'});
      const json = await res.json();
      setUsers(json);
      setLoading(false);
    }
    catch(err){
      console.log("Im catching the error");
      console.log(err);
      setUsers([]);
      setLoading(false);
    }
  }, [])

  useEffect(() => {
   fetchCoffeeData();
  },[fetchCoffeeData]) // 加入稳定后的依赖也不会触发循环

  return (
    <View style={styles.container}>
      {loading ? <Text>Loading...</Text> : <Text>Data fetched,共{users.length}条数据</Text>}
    </View>
  );
}

// 补全原代码缺失的styles定义
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

内容的提问来源于stack exchange,提问作者Javier Alejandro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 22:45:07