如何在React Native详情页添加更新与删除功能(DRF+React Native)
React Native + Django REST Framework 实现更新/删除功能指南
1. 修复导航配置(App.js)
首先需要在栈导航中添加编辑页面,同时修正函数组件中不能使用this的问题:
import React from 'react'; import { StyleSheet, Text, SafeAreaView, Image } from 'react-native'; import { NavigationContainer } from "@react-navigation/native"; import { createStackNavigator } from "@react-navigation/stack"; import { createDrawerNavigator } from '@react-navigation/drawer'; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import ListView from "./src/screens/components/function_list_view"; import DetailView from "./src/screens/components/detail_view"; import AddPizzeria from "./src/screens/drawer/addPizzeria.js"; import EditPizzeria from "./src/screens/drawer/editPizzeria.js"; // 导入编辑页面 import RegForm from "./src/screens/drawer/regForm.js"; import LoginForm from "./src/screens/drawer/loginForm.js"; import TabOne from "./src/screens/tabs/tab1.js"; import TabTwo from "./src/screens/tabs/tab2.js"; const Stack = createStackNavigator(); const Drawer = createDrawerNavigator(); const Tab = createBottomTabNavigator(); // 修正为普通函数,移除this const renderTabComponents = () => ( <Tab.Navigator> <Tab.Screen name="Tab 1" component={TabOne} /> <Tab.Screen name="Tab 2" component={TabTwo} /> </Tab.Navigator> ); // 修正为普通函数,添加编辑页面到栈 const renderScreenComponents = () => ( <Stack.Navigator> <Stack.Screen name="Home" component={ListView} /> <Stack.Screen name="Detail" component={DetailView} /> <Stack.Screen name="Tabs" children={renderTabComponents} /> <Stack.Screen name="EditPizzeria" component={EditPizzeria} /> </Stack.Navigator> ); export default function App() { return ( <NavigationContainer> <Drawer.Navigator> <Drawer.Screen name="Home" children={renderScreenComponents} /> <Drawer.Screen name="Add Pizza" component={AddPizzeria} /> <Drawer.Screen name="Registration" component={RegForm} /> <Drawer.Screen name="Login" component={LoginForm} /> </Drawer.Navigator> </NavigationContainer> ); } // 样式部分保持不变 const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#fff", alignItems: "center", justifyContent: "center", }, baseText: { color: "navy", fontSize: 30, fontStyle: "italic", }, newText:{ color: "red", }, pizzaImage: { width: 200, height: 200, }, })
2. 详情页添加编辑导航与删除功能(detail_view.js)
添加导航到编辑页的逻辑,同时实现删除请求:
import React, { useState, useEffect } from "react"; import { View, Text, Image, FlatList, Button, Alert } from "react-native"; import client from "./../../api/client"; import styles from "./detail_styles"; const DetailView = ({ route, navigation }) => { const [detail, setDetail] = useState({}); const { objurl } = route.params; const getDetail = async (url) => { try { const response = await client.get(url); if (response.ok) { setDetail(response.data); } } catch (error) { console.log(error); } }; // 删除披萨店逻辑 const handleDelete = async () => { Alert.alert( "确认删除", "确定要删除这家披萨店吗?", [ { text: "取消", style: "cancel" }, { text: "删除", style: "destructive", onPress: async () => { try { await client.delete(objurl); Alert.alert("成功", "披萨店已删除"); navigation.goBack(); } catch (error) { console.log(error); Alert.alert("错误", "删除失败,请稍后重试"); } } } ] ); }; useEffect(()=>{ getDetail(objurl); }, []) return ( <View style={styles.center}> <FlatList horizontal={true} data={detail.pizzeria_images || []} keyExtractor={(item) => item.id.toString()} renderItem={({ item }) => { return ( <Image style={styles.pizzaImage} source={{ uri: item.image, }} /> ); }} /> <Text style={styles.title}>Pizzeria: {detail.pizzeria_name}</Text> <Text style={styles.details}>Address: {detail.street}</Text> <Text style={styles.details}> City: {detail.city}, {detail.state},{detail.zip_code} </Text> <Text style={styles.details}>Web: {detail.website}</Text> <Text style={styles.details}>Ph: {detail.phone_number}</Text> <Text style={styles.details}>Description: {detail.description}</Text> <Text style={styles.details}>Email: {detail.email}</Text> {/* 编辑按钮 - 导航到编辑页并传递数据 */} <Button style={styles.addButton} onPress={() => navigation.navigate("EditPizzeria", { pizzeria: detail, objurl: objurl })} title="编辑" /> {/* 删除按钮 */} <Button style={styles.addButton} onPress={handleDelete} title="删除" color="red" /> </View> ); } export default DetailView;
3. 创建编辑页面(editPizzeria.js)
基于添加页面的结构修改,实现PUT更新请求:
import React, { useState } from "react"; import { SafeAreaView, ScrollView, TextInput, Button, Text, Alert } from "react-native"; import { Formik } from "formik"; import client from "./../../api/client"; import styles from "./addPizzeria_styles"; import validationSchema from "./addPizzeria_valid"; import PhotoPicker from "../components/shared/photo.js"; const EditPizzeria = ({ route, navigation }) => { const { pizzeria, objurl } = route.params; const [photo, setPhoto] = useState(pizzeria.logo_image?.image || ""); const updatedAlert = () => { Alert.alert("成功!", "披萨店信息已更新", [ { text: "返回详情页", onPress: () => navigation.goBack() }, ]); }; const handleSubmit = async (values) =>{ const data = new FormData(); data.append("pizzeria_name", values.pizzeria); data.append("street", values.street); data.append("city", values.city); data.append("state", values.state); data.append("zip_code", values.zip_code); data.append("website", values.website); data.append("phone_number", values.phone_number); data.append("description", values.description); data.append("email", values.email); // 仅当选择新图片时才传递,避免覆盖原有图片 if (photo) { data.append("logo_image", { uri: photo, name: "filename.jpg", type: "image/jpg", }); } try { await client.put(objurl, data); updatedAlert(); } catch(error) { console.log(error); Alert.alert("错误", "更新失败,请稍后重试"); }; }; return ( <Formik initialValues={{ pizzeria: pizzeria.pizzeria_name || "", street: pizzeria.street || "", city: pizzeria.city || "", state: pizzeria.state || "", zip_code: pizzeria.zip_code || "", website: pizzeria.website || "", phone_number: pizzeria.phone_number || "", description: pizzeria.description || "", email: pizzeria.email || "", }} onSubmit={handleSubmit} validationSchema={validationSchema} > {({ handleChange, handleSubmit, values, errors }) => ( <SafeAreaView style={styles.content}> <ScrollView> <PhotoPicker photo={photo} onPressPhoto={(uri) => setPhoto(uri)} /> <TextInput style={styles.textBox} value={values.pizzeria} placeholder="披萨店名称" onChangeText={handleChange("pizzeria")} /> <Text style={styles.error}>{errors.pizzeria}</Text> <TextInput style={styles.textBox} value={values.street} placeholder="街道地址" onChangeText={handleChange("street")} /> <Text style={styles.error}>{errors.street}</Text> <TextInput style={styles.textBox} value={values.city} placeholder="城市" onChangeText={handleChange("city")} /> <Text style={styles.error}>{errors.city}</Text> <TextInput style={styles.textBox} value={values.state} placeholder="州/省" onChangeText={handleChange("state")} /> <Text style={styles.error}>{errors.state}</Text> <TextInput style={styles.textBox} value={values.zip_code} placeholder="邮编" onChangeText={handleChange("zip_code")} /> <Text style={styles.error}>{errors.zip_code}</Text> <TextInput style={styles.textBox} value={values.website} placeholder="网站" onChangeText={handleChange("website")} /> <Text style={styles.error}>{errors.website}</Text> <TextInput style={styles.textBox} value={values.phone_number} placeholder="电话号码" onChangeText={handleChange("phone_number")} /> <Text style={styles.error}>{errors.phone_number}</Text> <TextInput style={styles.textBox} value={values.description} placeholder="描述" onChangeText={handleChange("description")} /> <Text style={styles.error}>{errors.description}</Text> <TextInput style={styles.textBox} value={values.email} placeholder="邮箱" onChangeText={handleChange("email")} /> <Text style={styles.error}>{errors.email}</Text> <Button style={styles.addButton} onPress={handleSubmit} title="更新" /> </ScrollView> </SafeAreaView> )} </Formik> )} export default EditPizzeria;
4. 后端验证
确保你的Django REST Framework视图支持PUT和DELETE请求:
- 使用
ModelViewSet自动支持CRUD操作 - 或单独配置
UpdateAPIView和DestroyAPIView - 序列化器需要设置
partial=True以支持部分字段更新
内容的提问来源于stack exchange,提问作者manny_22
相关产品推荐
相关产品推荐

