You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 16:55:27