React Redux更新表单(PUT请求)问题



我正在尝试更新一个表单,但有些东西无法正常工作。在我点击更新后,更新的信息会记录在控制台中,但状态管理的Redux端似乎不起作用。我在控制台中没有收到任何错误,但我的操作UPDATE_POST在Chrome上的Redux开发工具中都不可见。

这是代码:

UpdateForm组件:

import { useState , useEffect} from "react";
import { useHistory, useParams } from 'react-router-dom';
import jsonPlaceholder from "../apis/jsonPlaceholder";
import {updatePost} from '../actions'
import { useDispatch } from 'react-redux';
const UpdateForm = () => {
const dispatch = useDispatch()
const history = useHistory();
const { id } = useParams();
const [post, setPost] = useState({});
const [title, setTitle] = useState(post.title);
const [body, setBody] = useState(post.body);
const [author, setAuthor] = useState(post.author);
const fetchPost = async () => {
const response = await jsonPlaceholder.get(`/posts/${id}`)
console.log(response.data)
setPost(response.data)
setTitle(response.data.title)
setBody(response.data.body)
setAuthor(response.data.author)
return response.data
}
useEffect(() => {
fetchPost();
}, [])

const handleUpdate = async (e) => {
e.preventDefault();
const post = { title, body, author }
dispatch(updatePost(post))
console.log('post', post)//updated post is logged in console
history.push('/')
}
console.log("title", title)
return ( 
<div className="create">
<h2>Update Blog</h2>
<form>
<label>Blog title:</label>
<input
type="text"
required 
defaultValue={title}
onChange={(e) => setTitle(e.target.value)}
/>
<label>Blog body:</label>
<textarea
required
defaultValue={body}
onChange={(e) => setBody(e.target.value)}
></textarea>
<label>Author:</label>
<input
type="text"
required
defaultValue={author}
onChange={(e) => setAuthor(e.target.value)}
/>
<button onClick={handleUpdate}>Update</button>
</form>
</div>
);
}

export default UpdateForm;

行动:

export const updatePost = (post) => async dispatch => {
const res = await jsonPlaceholder.put(`posts/update/${post._id}`);
dispatch({
type: UPDATE_POST,
payload: res.data
})
}

和减速器:

import { ADD_POST, DELETE_POST, UPDATE_POST } from '../actions/types';
const postReducer = (state = [], action) => {
switch (action.type) {
case ADD_POST:
return state.concat([action.data]);
case UPDATE_POST:
return {
...state,
post: action.data
}
case DELETE_POST:
return state.filter((post)=>post.id !== action.id);
default:
return state
}
}
export default postReducer;

以下是node.js/express服务器端的请求:

router.put('/update/:id', async (req, res) => {
try {
let post = await Post.findOneAndUpdate(req.params.id, {
title: req.body.title,
body: req.body.body,
author: req.author.body
})
console.log('server', post)
return res.json(post)
} catch (error) {
console.error(error.message);
res.status(500).send('Server Error')
}
})

我现在收到服务器错误(500(,如果我删除author:req.author.body行,我就不会收到错误。前面的代码仍然不起作用。

正如我所看到的,你直接调用你的操作,而不是将其发送到

导入useDispatch并像这样使用

import { useDispatch } from "react-redux";

UpdateForm.js

const UpdateForm = () => {
....
const dispatch = useDispatch();
.....
const handleUpdate = async (e) => {
e.preventDefault();
const post = { title, body, author }
dispatch(updatePost(post))           // dispatch like this     
console.log('post', post)//updated post is logged in console
history.push('/')
}
console.log("title", title)
return ( 
<div className="create">
.......
</div>
);
}

export default UpdateForm;

减速器

您访问的不是action.payload,而是action.data

case UPDATE_POST:
return {
...state,
post: action.payload     
}

您需要调度updatePost操作,而不是直接调用它。您错过了useDispatch呼叫。

以下是React Redux文档的链接:

https://react-redux.js.org/api/hooks#usedispatch

示例:

import React from 'react'
import { useDispatch } from 'react-redux'
export const CounterComponent = ({ value }) => {
const dispatch = useDispatch()
return (
<div>
<span>{value}</span>
<button onClick={() => dispatch({ type: 'increment-counter' })}>
Increment counter
</button>
</div>
)
}

[更新]

刚刚注意到您的updatePost操作是一个更高阶的函数,所以一旦您将调用添加到useDispatch,您就需要将调用从更改为updatePost

updatePost(post)

updatePost(post)(dispatch)

老实说,我可能会选择书籍动作创建者,并将API调用转移到组件本身。如果你对异步操作感兴趣,我建议你研究一下react thunk,它很容易上手。

[更新2]

快递代码中似乎有一个拼写错误。

req.author.body

应该是

req.body.author

[更新3]

updatePost中的post对象不包含_id字段(请检查handleUpdate函数(,因此您将获得url:"posts/更新/未定义">

最新更新