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

React Native:返回ProjectsScreen时如何刷新FlatList组件

如何从CreateProjectScreen返回ProjectsScreen时自动刷新FlatList?

问题场景

开发React Native项目创建应用时,主屏幕ProjectsScreen包含的<ProjectsList/>组件通过useProjects hook加载数据。在CreateProjectScreen成功创建新项目并返回主屏幕后,FlatList不会自动更新(数据已保存,仅能通过下拉刷新触发更新),需要实现返回时自动刷新列表。

解决方案

方法1:监听屏幕Focus事件(最直接适配现有代码)

利用React Navigation的focus事件,每次ProjectsScreen获得焦点时重新加载数据。修改ProjectsScreen代码:

const ProjectsScreen = ({ navigation }) => {
  const [apiResult, setApiResult] = useState(null);
  const [apiError, setApiError] = useState(null);
  const { reloadProjects } = useProjects();
  const { t } = useTranslation();

  // 监听屏幕focus事件,每次返回时刷新数据
  useEffect(() => {
    const unsubscribe = navigation.addListener('focus', () => {
      reloadProjects();
    });

    // 组件卸载时清理监听
    return unsubscribe;
  }, [navigation, reloadProjects]);

  // 初始加载数据
  useEffect(() => {
    reloadProjects();
  }, []);

  // 原有返回部分保持不变
  return (
    <SafeAreaView style={styles.container}>
      <Text style={styles.title}>{t("title.projects")}</Text>
      <View style={styles.viewContainer}>
        <View style={styles.projectsContainer}>
          <ProjectsList navigation={navigation} />
        </View>
        <View style={styles.buttonContainer}>
          <StyledButton
            whiteBtn={true}
            title={t("buttons.new_project")}
            navigation={navigation}
            onPress={() => navigation.navigate("CreateProject")}
          />
        </View>
      </View>
    </SafeAreaView>
  );
};

方法2:优化全局状态管理(减少API请求,适合长期维护)

将项目状态升级为全局共享状态,创建新项目后直接更新全局状态,无需重新请求API。

  1. 创建ProjectContext.js全局状态文件:
import { createContext, useContext, useState, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import axios from 'axios';

const ProjectContext = createContext();

export const ProjectProvider = ({ children }) => {
  const [projects, setProjects] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  const fetchProjects = async () => {
    setIsLoading(true);
    const token = await AsyncStorage.getItem("access_token");
    const config = {
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/json",
        Accept: "application/json",
      },
    };

    try {
      const response = await axios.get("http:/asof/v1/projects/", config);
      if (response.status === 200) {
        setProjects(response.data);
      } else {
        throw new Error(`HTTP error! Status: ${response.status}`);
      }
    } catch (error) {
      console.error("Error fetching projects:", error.message);
    } finally {
      setIsLoading(false);
    }
  };

  // 新增:直接向全局状态添加新项目
  const addProject = (newProject) => {
    setProjects(prev => [...prev, newProject]);
  };

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

  return (
    <ProjectContext.Provider value={{ projects, isLoading, fetchProjects, addProject }}>
      {children}
    </ProjectContext.Provider>
  );
};

export const useProjects = () => {
  const context = useContext(ProjectContext);
  if (!context) {
    throw new Error('useProjects must be used within a ProjectProvider');
  }
  return context;
};
  1. 修改CreateProjectScreen的sendApi函数,创建成功后直接更新全局状态:
const sendApi = async (
  values,
  setApiResult,
  setApiError,
  { navigation },
  addProject // 替换原reloadProjects为addProject
) => {
  try {
    const token = await AsyncStorage.getItem("access_token");
    const config = {
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/json",
        Accept: "application/json",
      },
    };

    const data = {
      name: values.name,
      description: values.description,
      models_uuid: values.models_uuid,
    };

    const response = await axios.post("http://asof/v1/projects/", data, config);

    if (response.status === 201) {
      console.log("Project created successfully");
      Alert.alert("Project created successfully");
      addProject(response.data); // 直接添加新项目到全局状态
      navigation.navigate("ProjectsScreen");
      setApiResult(response.data);
    } else {
      console.log(response);
      setApiError("Error al crear el proyecto");
    }
  } catch (error) {
    setApiError(error.message);
    console.log("Error en la solicitud POST:", error);
  }
};

// 同时修改CreateProjectScreen中useProjects的调用:
function CreateProjectScreen({ navigation }) {
  // ...
  const { addProject } = useProjects(); // 获取addProject方法
  // ...
  onSubmit={async (values) => {
    values.models_uuid = selectedModelUUIDs;
    await sendApi(
      values,
      setApiResult,
      setApiError,
      { navigation },
      addProject // 传递addProject到sendApi
    );
  }}
  // ...
}
  1. 在App根组件中包裹ProjectProvider,确保所有组件能访问全局状态:
import { ProjectProvider } from './ProjectContext';

export default function App() {
  return (
    <ProjectProvider>
      {/* 原有导航或根组件 */}
    </ProjectProvider>
  );
}

说明

  • 方法1无需修改状态结构,快速解决问题,适合当前代码规模。
  • 方法2通过全局状态减少API请求次数,提升性能,适合应用长期迭代维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:47:02