【问题标题】:React-Redux Update Form (PUT request) issueReact-Redux 更新表单(PUT 请求)问题
【发布时间】:2021-06-18 09:52:50
【问题描述】:

我正在尝试更新表单,但某些内容无法正常工作。我点击更新后,控制台中记录了更新的信息,但是状态管理的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,我不会收到错误。前面的代码还是不行。

【问题讨论】:

  • 你的代码看起来不错。你能在const res = await jsonPlaceholder.put('posts/update/${post._id}'); 后面加一个console.log(res)吗?
  • 好像也有服务器错误。这是请求。 router.put('/update/:id', async (req, res) => { try { let post = await Post.findOneAndUpdate(req.params.id, { title: req.body.title, body: req. body.body,作者:req.author.body }) console.log('server', post) return res.json(post) } catch (error) { console.error(error.message); res.status(500 ).send('服务器错误') } })
  • 顺便说一句,这是我在控制台记录响应时得到的:url:“posts/update/undefined”,方法:“put”,标题:{…},baseURL:“localhost:500以及错误的 response.data 对象(它返回的对象的 id 与单击的对象不同)
  • author: req.author.body 替换为author: req.body.author 并检查res.data 在您的前端代码中是否正确
  • 嗯,感谢您发现这一点。我替换了它,现在它在 Postman 上运行良好,只是我需要发送两次请求(第一次返回 null,第二次返回数据)。

标签: reactjs forms redux react-redux put


【解决方案1】:

您需要调度 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)

老实说,我可能会选择 book action creator 并将 API 调用移至组件本身。如果您对异步操作感兴趣,我建议您研究一下 react-thunk,它很容易开始。

[更新 2]

快递代码好像有错别字。

req.author.body

应该是

req.body.author

[更新 3]

updatePost 中的 post 对象不包含 _id 字段(检查您的 handleUpdate 函数)因此您将获得 url:“posts/update/undefined”

【讨论】:

  • 我刚做了,我更新了代码。现在我可以在 Redux 开发工具中看到正在调度的操作,但我仍然没有将更新更改保存到数据库中。我在控制台中没有收到任何请求错误。也许我在 action 或 reducer 中做的不对?
  • 您是否也看到了更新的答案?注意到在写了原版之后。
  • 是的,我都试过了:dispatch(updatePost(post)) 和 updatePost(post)(dispatch) 但没有区别。它仍然无法正常工作。
  • 我会检查 jsonPlaceholder 返回的承诺是否真的按照原帖评论中的建议解析。
  • promise 在前端解决了吗?
【解决方案2】:

正如我所见,您是直接调用您的操作而不是调度它

导入 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.data,而不是action.payload

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

【讨论】:

  • 我刚刚做到了。我更新了问题,您可以看到更改。现在我在 Redux 开发工具中得到了这个动作,这意味着它被分派了,但我仍然没有得到保存的更新。我也没有收到任何控制台错误。
  • @Monika 你能分享你的响应数据结构吗
  • 这里是作者:“Irena”正文:null createdAt:“2021-03-18T10:15:13.750Z”标题:null updatedAt:“2021-03-21T16:48:52.852Z” __v:0 _id:“605328314500da477ccd39e0”
猜你喜欢
  • 2019-09-23
  • 1970-01-01
  • 2021-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2020-10-01
  • 2022-12-21
相关资源
最近更新 更多