返回屏幕并获取新数据时如何从屏幕刷新平面列表组件(React Native)

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

我正在尝试制作一个应用程序,您可以在其中创建一些项目,在主屏幕(“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>
    )
}

提前谢谢你:)

我在添加新项目后成功获取新数据,但不知道如何从主屏幕刷新组件

javascript reactjs react-native react-native-flatlist uirefreshcontrol
1个回答
0
投票

在 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 不同时,您的应用程序都会重新加载项目。

© www.soinside.com 2019 - 2024. All rights reserved.