如何在使用 navigation.navigate() 导航回 React Native 组件后重新获取数据?

问题描述 投票:0回答:1

我有一个 React Native 应用程序,在添加新服务后我将导航到 StudioServices 屏幕。但是,当导航回 StudioServices 屏幕时,不会重新获取数据。出现此问题的原因是 useStudioServices 挂钩仅在组件最初安装时才获取数据,而不是在返回导航后屏幕获得焦点时获取数据。

设置如下:

StudioServices 屏幕 - 显示服务列表。 useStudioServices Hook - 从 API (GetStudioServices) 获取数据并返回服务、加载和错误状态。 ServiceAdd 屏幕 - 保存新服务后导航至 StudioServices。

const StudioServices = () => {
const { services, loading, error } = useStudioServices();

if (loading) {
  return <LoadingScreen />;
}

if (error) {
  return (
    <View>
      <Text>Error</Text>
    </View>
  );
}

return <ServiceList services={services} />;
};

useStudioServices 挂钩:

export const useStudioServices = () => {
  const [services, setServices] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  const fetchData = async () => {
    try {
      setLoading(true);
      const result = await GetStudioServices();
      setServices(result);
    } catch (error) {
      setError(error);
    } finally {
      setLoading(false);
    }
  };
  
  useEffect(() => {
    fetchData();
  }, []);

  return { services, loading, error };
};

服务添加屏幕:

const ServiceAdd = () => {
  const navigation = useNavigation();

  const handleSave = async (newService) => {
    await InsertService(newService);
    navigation.navigate("StudioServices", { newService });
  };
};
  • 导航到 ServiceAdd 屏幕并保存新服务后,当我使用 navigation.navigate("StudioServices") 导航回 StudioServices 屏幕时,不会重新获取数据。

  • useStudioServices 挂钩中的 useEffect 仅在组件首次安装时运行一次,但在我导航回来时则不会运行一次。

reactjs react-native react-hooks expo
1个回答
0
投票

您必须在挂钩文件中进行一些更改,请参阅下面的代码:

import { useState, useCallback } from 'react';

export const useStudioServices = () => {
  const [services, setServices] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  const fetchData = useCallback(async () => {
    try {
      setLoading(true);
      const result = await GetStudioServices();
      setServices(result);
    } catch (error) {
      setError(error);
    } finally {
      setLoading(false);
    }
  }, []); // useCallback ensures the function reference remains stable

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

  return { services, loading, error, fetchData };
};

现在,当您返回屏幕时,您可以在屏幕中调用 fetchData,有两种方法,一种是使用导航监听器,另一种是使用 useFocusEffect 和 useCallback 挂钩。

带挂钩:

import { useFocusEffect } from '@react-navigation/native';

const StudioServices = () => {
  const { services, loading, error, fetchData } = useStudioServices();

  // Refetch data whenever the screen comes into focus
  useFocusEffect(
    React.useCallback(() => {
      fetchData();
    }, []) // Add dependencies if needed
  );

  if (loading) {
    return <LoadingScreen />;
  }

  if (error) {
    return (
      <View>
        <Text>Error</Text>
      </View>
    );
  }

  return <ServiceList services={services} />;
};

带有导航列表:

import { useEffect } from 'react';
import { useNavigation } from '@react-navigation/native';

const StudioServices = () => {
  const navigation = useNavigation();
  const { services, loading, error, fetchData } = useStudioServices();

  useEffect(() => {
    const unsubscribe = navigation.addListener('focus', () => {
      fetchData();
    });

    return unsubscribe; // Cleanup the listener when the component unmounts
  }, [navigation, fetchData]);

  if (loading) {
    return <LoadingScreen />;
  }

  if (error) {
    return (
      <View>
        <Text>Error</Text>
      </View>
    );
  }

  return <ServiceList services={services} />;
};
© www.soinside.com 2019 - 2024. All rights reserved.