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

使用react-navigation-bottom-tab切换屏幕时useEffect不生效的问题

问题解决:react-navigation-bottom-tab切换时HomeScreen的useEffect不触发

问题原因

react-navigation的底部标签导航(Bottom Tab Navigator)默认会保留每个标签页对应的组件实例,切换标签时不会卸载/重新挂载组件。因此你写的空依赖useEffect(() => { fetchRides(); }, [])只会在HomeScreen第一次挂载时执行一次,之后从ProfileScreen切回HomeScreen时,组件未重新挂载,这个useEffect不会再次触发。

解决方案

使用react-navigation提供的useFocusEffect钩子,它会在屏幕获得焦点时触发回调,正好匹配你需要在切回HomeScreen时重新获取数据的需求。

修改后的HomeScreen.js代码

import {
  View,
  FlatList,
  StyleSheet,
} from "react-native";
import { RideCard } from "./RideCard";
import { OneTouchFilter } from "./OneTouchFilter";
import { useFirestoreContext } from "../../contexts/FirestoreContext";
import { useEffect, useCallback } from "react";
// 导入useFocusEffect
import { useFocusEffect } from "@react-navigation/native";

export const HomeScreen = ({ navigation }) => {
  console.log("HomeScreen.js useEffect");
  const { selectedBoardType, cityFromText, cityToText, fetchRides, rides } =
    useFirestoreContext();

  // 替换原来的空依赖useEffect
  useFocusEffect(
    useCallback(() => {
      fetchRides();
    }, [fetchRides])
  );
  
  useEffect(() => {
    fetchRides();
  }, [selectedBoardType, cityFromText, cityToText, fetchRides]);

  return (
    <View style={styles.inner}>
      <OneTouchFilter />
      <FlatList
        data={rides}
        renderItem={(itemData) => (
          <RideCard
            ride={itemData.item}
            index={itemData.index}
            id={itemData.item.id}
            numOfRides={rides.length}
          />
        )}
      />
    </View>
  );
};

补充说明

  • useFocusEffect必须配合useCallback使用,避免每次渲染创建新回调函数引发不必要的触发。
  • 把fetchRides加入依赖数组,确保回调能获取到最新的函数实例,同时消除React的依赖警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:25:18