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

为何使用多个useFocusEffect会导致屏幕组件渲染两次?

问题原因分析

你的组件在屏幕获得焦点时渲染两次,核心原因如下:

  • 两个useFocusEffect各自触发了异步API请求,每个请求完成后都调用setMyState2更新同一个状态。React中每次调用setState都会触发组件重新渲染,两次状态更新就导致了两次额外的渲染。
  • 你两个请求的是完全相同的接口,却重复发起请求并更新同一个state,这属于冗余操作,进一步加剧了重复渲染的问题。
解决方案

1. 合并请求与Effect(推荐)

既然两个请求的接口完全一致,直接合并成一个useFocusEffect,只发起一次请求,避免冗余操作和重复渲染:

import { useFocusEffect } from '@react-navigation/native';
import axios from 'axios';
import React, { useState } from 'react'
import { View } from 'react-native'

let renderCount = 0;

function TestScreen() {

  const [myState2, setMyState2] = useState<any>();

  renderCount++;
  console.log("component render number: ", renderCount);

  useFocusEffect(
    React.useCallback(async () => {
      const { data } = await axios.get<any>('https://dummyjson.com/quotes?limit=30');
      setMyState2(data);
    }, [])
  );

  return (
    <View></View>
  )
}

export default TestScreen

2. 若需独立请求,更新不同状态

如果确实需要两个独立的API请求(假设后续会修改为不同接口),请确保它们更新不同的state,避免重复修改同一个状态导致的多次渲染:

// 修改fetch函数,分别更新不同state
const fetchAPIData1 = async () => {
  const { data } = await axios.get<any>('https://dummyjson.com/quotes?limit=30');
  setMyState1(data); // 更新myState1
}

const fetchAPIData2 = async () => {
  const { data } = await axios.get<any>('https://dummyjson.com/quotes?limit=30');
  setMyState2(data); // 更新myState2
}

3. 避免重复请求(可选)

如果不需要每次屏幕获得焦点都重新请求数据,可以用useRef标记是否已完成首次请求:

const isDataLoaded = useRef(false);

useFocusEffect(
  React.useCallback(async () => {
    if (!isDataLoaded.current) {
      const { data } = await axios.get<any>('https://dummyjson.com/quotes?limit=30');
      setMyState2(data);
      isDataLoaded.current = true;
    }
  }, [])
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 03:11:18