我正在尝试制作一个应用程序,您可以在其中创建一些项目,在主屏幕(“ProjectsScreen”)上执行此操作,我有一个组件可以在渲染时从 fetchProjects 获取数据。
创建新项目后出现问题。要创建项目,我导航到“CreateProjectScreen”,在创建新项目时,我导航回到“ProjectsScreen”,它不会使用新数据进行更新。
创建项目后的新数据已正确保存,但平面列表未刷新,此时我已经通过滚动刷新实现了这一点
当我回到 ProjectScreen 时如何刷新平面列表
这就是代码的结构
-项目屏幕 --项目列表 ---获取项目 -创建项目屏幕
我添加以下代码
项目屏幕:
const ProjectsScreen = ({ navigation }) => {
const [apiResult, setApiResult] = useState(null);
const [apiError, setApiError] = useState(null);
const { reloadProjects } = useProjects()
const { t } = useTranslation()
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>
);
};
项目列表组件:
const ProjectsList = ({ navigation }) => {
const { projects, isLoading, reloadProjects } = useProjects();
const [refreshing, setRefreshing] = useState(false);
const onRefresh = useCallback(() => {
setRefreshing(true);
setTimeout(() => {
reloadProjects();
setRefreshing(false);
}, 2000);
}, []);
return (
<View style={styles.container}>
{isLoading ? (
<ActivityIndicator size='large' colors={COLORS.primary} />
) : (
<FlatList
data={projects}
keyExtractor={(project) => project.uuid}
renderItem={({ item: project }) => (
<TouchableOpacity onPress={() => navigation.navigate("Upload", {project})}>
<View style={styles.projectContainer}>
<View style={{ flexDirection: "row", justifyContent: 'space-between' }}>
<Text style={styles.title}>{project.name}</Text>
<TouchableOpacity
onPress={() => handleDeletePress(project, reloadProjects)}>
<Image
style={{ marginTop: 12 }}
source={icons.del} />
</TouchableOpacity>
</View>
<Text style={styles.description}>{project.description}</Text>
{/* <Text>UUID: {project.uuid}</Text> */}
{project.models && project.models.length > 0 && (
<View style={styles.modelsContainer}>
{/* <Text style={styles.modelsHeader}>Models:</Text> */}
<FlatList
data={project.models}
keyExtractor={(model) => model.uuid}
renderItem={({ item: model }) => (
<View style={styles.modelContainer}>
{/* <LinearGradient colors={['#FF4D00', '#FF00D6']} style={styles.gradient}> */}
<Text style={styles.modelsName}>{model.name}</Text>
<Text style={styles.modelsDesc}>{model.description}</Text>
{/* <Text>UUID: {model.uuid}</Text> */}
{/* </LinearGradient> */}
</View>
)}
showsHorizonralScrollIndicator={false}
horizontal
/>
</View>
)}
</View>
</TouchableOpacity>
)}
showsVerticalScrollIndicator={false}
refreshing={refreshing} // Added pull to refesh state
onRefresh={onRefresh} // Added pull to refresh control
ListEmptyComponent={<Text style={{fontSize: SIZES.medium}}>{t("error.projects")} :( {"\n\n"}{t("error.refresh")}</Text>}
/>
)}
</View>
);
};
获取项目:
const useProjects = () => {
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) {
throw new Error(`HTTP error! Status: ${response.status}`);
} else {
setProjects(response.data);
}
} catch (error) {
console.log(error)
console.error('Error fetching repositories:', error.message);
} finally {
setIsLoading(false);
}
};
useEffect(() => {
fetchProjects();
}, []);
return { projects, isLoading, reloadProjects: fetchProjects };
};
export default useProjects;
创建项目屏幕:
const initialValues = {
name: '',
description: '',
models_uuid: [],
}
const sendApi = async (values, setApiResult, setApiError, { navigation }, reloadProjects) => {
try {
// Obtén el token de AsyncStorage
const token = await AsyncStorage.getItem('access_token');
// Configuración de la solicitud
const config = {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
'Accept': 'application/json',
},
};
// Datos del cuerpo de la solicitud
const data = {
name: values.name,
description: values.description,
models_uuid: values.models_uuid,
};
// Realiza la solicitud POST
const response = await axios.post(
'http://asof/v1/projects/',
data,
config
);
// Maneja la respuesta
if (response.status === 201) {
console.log("Project created successfully");
Alert.alert("Project created successfully")
navigation.navigate("ProjectsScreen")
reloadProjects()
// Si es necesario, puedes manejar el resultado de la API
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);
}
};
function CreateProjectScreen({ navigation }) {
const [apiResult, setApiResult] = useState(null);
const [apiError, setApiError] = useState(null);
const { login } = useContext(AuthContext)
const { reloadProjects } = useProjects(); // Obtén reloadProjects del hook useProjects
const [selectedModelUUIDs, setSelectedModelUUIDs] = useState([]);
const { t } = useTranslation()
const handleModelsSelect = (modelUUIDs) => {
setSelectedModelUUIDs(modelUUIDs);
console.log("Modelos seleccionados: ", selectedModelUUIDs)
};
return (
<SafeAreaView style={styles.container}>
<Text style={styles.title}>{t("title.create")}</Text>
<Formik
validationSchema={ProjectValidationSchema}
initialValues={initialValues}
onSubmit={async values => {
values.models_uuid = selectedModelUUIDs;
console.log(values)
console.log('Submitting project:', values);
await sendApi(values, setApiResult, setApiError, { navigation }, reloadProjects);
}}
>
{({ values, handleChange, handleSubmit }) => {
const { name, description, password, repeatPassword } = values
return <View style={styles.container}>
<Text style={styles.text}>{t("name")}</Text>
<FormikInputValue
value={name}
onChangeText={handleChange("name")}
name='name'
placeHolder={t("name")}
image={icons.user}
/>
<Text style={styles.text}>{t("description")}</Text>
<FormikInputValue
value={description}
onChangeText={handleChange("description")}
name='description'
placeHolder={t("description")}
image={icons.mail}
/>
<ModelsList onModelsSelect={handleModelsSelect} />
<View style={styles.loginButton}>
{apiError && <Text style={{ color: "#ff0000" }}>{t("error.api_error")}: {apiError}</Text>}
<StyledButton
onPress={(handleSubmit)}
title={t("buttons.create")}
whiteBtn={true}
/>
</View>
</View>
}}
</Formik>
</SafeAreaView>
)
}
提前谢谢你:)
我在添加新项目后成功获取新数据,但不知道如何从主屏幕刷新组件
在 ProjectsScreen 中,您可以在
reloadProjects
挂钩内调用 useEffect
。您可以尝试使用 react-navigation库中的
useEffect
更改 useFocusEffect
https://reactnavigation.org/docs/use-focus-effect/
另一种解决方法是在导航回项目屏幕期间传递属性。
if (response.status === 201) {
console.log("Project created successfully");
Alert.alert("Project created successfully")
navigation.navigate("ProjectsScreen")
reloadProjects()
// Si es necesario, puedes manejar el resultado de la API
setApiResult(response.data);
} else {
console.log(response);
setApiError("Error al crear el proyecto");
}
您拨打
navigation.navigate("ProjectsScreen")
的地方,您就可以做 navigation.navigate("ProjectsScreen", {lastTimeReloadedAt: new Date().getTime() })
。 // 如果您想在每次导航回此屏幕时重新加载项目。
if (response.status === 201) {
console.log("Project created successfully");
Alert.alert("Project created successfully")
setApiResult(response.data);
navigation.navigate("ProjectsScreen", {
lastTimeReloadedAt: new Date().getTime()
})
// reloadProjects() No need to call this here.
// Si es necesario, puedes manejar el resultado de la API
} else {
console.log(response);
setApiError("Error al crear el proyecto");
}
现在您可以将 ProjectsScreen 修改为
const ProjectsScreen = ({ navigation, route }) => {
const [apiResult, setApiResult] = useState(null);
const [apiError, setApiError] = useState(null);
const { reloadProjects } = useProjects()
const { t } = useTranslation()
useEffect(() => {
reloadProjects()
}, [route.params.lastTimeReloadedAt])
...}
在这种情况下,每次 LastTimeReloadedAt 不同时,您的应用程序都会重新加载项目。