Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 已解决:为什么Django管理员列表不从前端表单更新编辑?_Reactjs_Django_Django Rest Framework_React Hooks_Use Effect - Fatal编程技术网

Reactjs 已解决:为什么Django管理员列表不从前端表单更新编辑?

Reactjs 已解决:为什么Django管理员列表不从前端表单更新编辑?,reactjs,django,django-rest-framework,react-hooks,use-effect,Reactjs,Django,Django Rest Framework,React Hooks,Use Effect,我试图通过以下方式在DRF Reactjs中创建一个CRUD应用程序 我已经成功地实现了添加、删除、列表视图。但我正在尝试编辑一个特定的行,它没有在DRF后端更新。但编辑的行显示在前端列表中。为什么它没有在django管理员列表中更新 在DRF side view.py中: @api_view(['POST']) def TodoUpdate(request, pk): todo = Todo.objects.get(id=pk) serializer = TodoSeriali

我试图通过以下方式在DRF Reactjs中创建一个CRUD应用程序

我已经成功地实现了添加、删除、列表视图。但我正在尝试编辑一个特定的行,它没有在DRF后端更新。但编辑的行显示在前端列表中。为什么它没有在django管理员列表中更新

在DRF side view.py中:

@api_view(['POST'])
def TodoUpdate(request, pk):
    todo = Todo.objects.get(id=pk)
    serializer = TodoSerializer(instance=todo, data=request.data)

    if serializer.is_valid():
        serializer.save()

    return Response(serializer.data)
我使用cors头来连接前端和后端。以下是用于编辑的前端代码:

App.js:

import React,{Fragment, useState,useEffect} from 'react'
import EditList from './components/EditList';
import axios from 'axios'
     
export default function App() {
  const initialTodoSate = { id: null, title: "", body: "" };
  const [todos, setTodos] = useState([]);
  const [todoList, setTodolist] = useState(initialTodoSate);
  const [editing, setEditing] = useState(false);

  useEffect(()=>{
    axios.get("http://localhost:8000/api/todo-list",{})
    .then(res=>{
      setTodos(res.data)
    }).catch(err=>{
      console.log(err)
    })
  },[]) 
  
   const addTodoList = (todo) => {

    axios
      .post("http://localhost:8000/api/todo-create/",todo)
      .then((res) => {
        console.log(res.data);
       todo.id = todos.length + 1;
        setTodos([todo, ...todos]); 
      })
      .catch((err) => {
        console.log(err);
      });
  };
  const deleteTodo = (id) => {
    setEditing(false);
    axios.delete(`http://localhost:8000/api/todo-delete/${id}/`)
    .then(res=>{
      setTodos(todos.filter((todo) => todo.id !== id));
    }).catch(err=>{
      console.log(err)
    })
  };

 const updateTodo = ( id,updatedTodo) => {
   axios
     .post(`http://localhost:8000/api/todo-update/${id}/`, id)
     .then((res) => {
       console.log(res.data);
     })
     .catch((err) => {
       console.log(err);
     });
   setEditing(false);
   setTodos(todos.map((todo) => (todo.id === id ? updatedTodo : todo)));
 };

  const editRow = (todo) => {
    setEditing(true);

    setTodolist({
      id: todo.id,
      title: todo.title,
      description: todo.description,
    });
  };
  return (
    <div className="container">
      <h1>Django-based Todo with React Hooks</h1>
      {editing ? (
        <Fragment>
          <h3>Edit Task</h3>
          <EditList
            editing={editing}
            setEditing={setEditing}
            todoList={todoList}
            updateTodo={updateTodo}
          />
        </Fragment>
      ) : (
        <Fragment>
          <CreateTodo addTodoList={addTodoList} />
          <hr />
        </Fragment>
      )}
      <div className="flex-row">
        <div className="flex-large">
          <TodoList todos={todos} editRow={editRow} deleteTodo={deleteTodo} />
        </div>
      </div>
    </div>
  );
}
import React,{Fragment,useState,useffect}来自'React'
从“/components/EditList”导入EditList;
从“axios”导入axios
导出默认函数App(){
const initialTodoSate={id:null,title:,body::};
const[todos,setTodos]=useState([]);
const[todoList,setTodolist]=useState(initialToDoState);
const[editing,setEditing]=使用状态(false);
useffect(()=>{
axios.get(“http://localhost:8000/api/todo-列表“,{})
。然后(res=>{
setTodos(res.data)
}).catch(错误=>{
console.log(错误)
})
},[]) 
常量addTodoList=(todo)=>{
axios
.post(“http://localhost:8000/api/todo-创建/”,todo)
。然后((res)=>{
console.log(res.data);
todo.id=todos.length+1;
setTodos([todo,…todos]);
})
.catch((错误)=>{
控制台日志(err);
});
};
常量deleteTodo=(id)=>{
设置编辑(假);
axios.delete(`http://localhost:8000/api/todo-删除/${id}/`)
。然后(res=>{
setTodos(todos.filter((todo)=>todo.id!==id));
}).catch(错误=>{
console.log(错误)
})
};
const updateTodo=(id,updateTodo)=>{
axios
.邮政(`http://localhost:8000/api/todo-更新/${id}/`,id)
。然后((res)=>{
console.log(res.data);
})
.catch((错误)=>{
控制台日志(err);
});
设置编辑(假);
setTodos(todos.map((todo)=>(todo.id==id?updatedTodo:todo));
};
const editRow=(todo)=>{
设置编辑(真);
塞托多利斯特({
id:todo.id,
标题:todo.title,
description:todo.description,
});
};
返回(
基于Django的带有React钩子的Todo
{编辑(
编辑任务
) : (

)} ); }
和EditList.js:

import React, { useState,useEffect } from "react";

export default function EditList({ todoList, setEditing, updateTodo }) {
  const [todo, setTodo] = useState([todoList]);
  useEffect(() => {
        setTodo(todoList);
  }, [todoList]);
  const handleChange = (e) => {
    const { name, value } = e.target;
    setTodo({ ...todo, [name]: value });
  };
  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        updateTodo(todo.id, todo);
      }}
    >
      <label>Title:</label>
      <br />
      <input
        type="text"
        name="title"
        value={todo.title}
        onChange={handleChange}
      />
      <br />
      <label>Description:</label>
      <br />
      <input
        type="text"
        name="body"
        value={todo.body}
        onChange={handleChange}
      />
      <br />
      <button>Update Task</button>
      <button onClick={() => setEditing(false)} className="button muted-button">
        Cancel
      </button>
    </form>
  );
}
import React,{useState,useffect}来自“React”;
导出默认函数EditList({todoList,setEditing,updateTodo}){
const[todo,setTodo]=useState([todoList]);
useffect(()=>{
setTodo(todoList);
},[todoList]);
常数handleChange=(e)=>{
常量{name,value}=e.target;
setTodo({…todo[name]:value});
};
返回(
{
e、 预防默认值();
updateTodo(todo.id,todo);
}}
>
标题:


说明:

更新任务 setEditing(false)}className=“按钮静音按钮”> 取消 ); }
当我试图编辑一行标题和正文时,它会被编辑,按下更新按钮后,更新的行会包含在列表中。但问题是,当我查看django管理员时,它还没有更新,当我检查开发工具时,我发现了一个错误:

警告:组件正在将非受控输入更改为受控输入。这可能是由值从未定义更改为已定义的值引起的,这是不应该发生的。在组件的使用寿命内,决定使用受控或非受控输入元件。更多信息: 输入时 在形式上 编辑列表(http://localhost:3000/static/js/main.chunk.js:511:3) 在div 应用程序(http://localhost:3000/static/js/main.chunk.js:70:83) 控制台@vendors~main.chunk.js:31671

我哪里出了错

有人能帮我吗?如果您需要任何其他代码或信息,请告诉我

  • 尝试更新应该在put请求中完成,而不是post请求。这是一个RESTAPI约定,但是一个差异可能会带来一些后果
  • 在这种情况下,开发工具中的错误告诉您,您的一个组件有一个onChange/onSubmit etc属性,该属性在一次装载过程中从null变为函数。这并不是导致问题的原因,但我怀疑可以通过在handleSubmit函数中声明代码,然后将其放入onSubmit中来修复问题
  • 我认为实际导致您的问题的错误是updatedTodo没有被发送到后端。发送的只是id(axios.post的第二个参数)。因此,如果您在执行期间暂停后端,您将看到request.data=仅id,而它应该是TodoSerializer的可读字段
  • 附言:

  • 您可以在updateToDo异步请求错误之后的代码中添加一个“debugger;”语句,以查看错误的实际情况(阅读有关开发工具调试的更多信息-依赖于浏览器)
  • 不要滥用片段——在这种情况下,如果在大多数组件中使用div,将有助于获得更易于访问的体验。如果将某些内容的标题与内容分组,是否更有意义
    我跟着你的1号,2号和PS号。它就像火车一样工作。。。thanx,伙计。很抱歉,我没有及时回复。你回答这个问题时,我正在睡觉。这里是午夜。