我有一个 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 仅在组件首次安装时运行一次,但在我导航回来时则不会运行一次。
您必须在挂钩文件中进行一些更改,请参阅下面的代码:
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} />;
};