【问题标题】:React form state mutated by submit function由提交函数改变的反应表单状态
【发布时间】:2020-06-11 04:30:55
【问题描述】:

我正在自学 React,并使用 Axios API 构建一个小型单页 React 应用程序。我有一个不断失败的 POST 请求。 console.log 的广泛使用似乎表明表单输入的状态在某种程度上被提交函数改变了,尽管我不知道为什么。救命!

代码如下:

import React, { useState, useEffect } from 'react'
import axios from 'axios'
import { Grid, TextField, Button, Typography } from '@material-ui/core'
import { FaHome } from 'react-icons/fa'

const AddItem = ({ setShowAddItem }) => {
    const [inputs, setInputs] = useState()
    const [submitted, setSubmitted] = useState(false)

    useEffect(() => {
        console.log(`Type: ${typeof inputs} Data: ${inputs}`)
        if (inputs) {
            console.log('executing POST')
            console.log(`Inside if() Type: ${typeof inputs} Data: ${inputs}`)
            axios.post('/api/ItemModels', { ...inputs })
                .then(res => {
                    console.log(res.data)
                })
                .catch(err => console.error(err))
            setInputs()
            setSubmitted(false)
        }
    }, [submitted])

    const handleInputChange = event => {
        setInputs({ ...inputs, [event.target.name]: event.target.value })
        console.log(inputs)
        console.log(typeof inputs)
    }

    const handleSubmit = event => {
        console.log("handleSubmit triggered")
        if (event) {
            console.log("if() in handleSubmit triggered")
            console.log(`Inside handleSubmit Data: ${inputs}`)
            event.preventDefault()
            setSubmitted(true)
        }
    }

    return (
        <>
            <Grid container className="form-container">
                <Typography variant="h3">Add an Item</Typography>
                <form noValidate onSubmit={handleSubmit}>
                    <TextField name="shape" label="Shape" onChange={handleInputChange} required />
                    <TextField name="size" label="Size" onChange={handleInputChange}  required />
                    <TextField name="color" label="Color" onChange={handleInputChange} required />
                    <TextField name="clarity" label="Clarity" onChange={handleInputChange} required />
                    <TextField name="price" label="Price" onChange={handleInputChange} required />
                    <TextField name="listPrice" label="List Price" onChange={handleInputChange} required />

                    <Button type="submit">
                        Submit
                    </Button>
                </form>
            </Grid>

            <Button type="button" onClick={() => setShowAddItem(false)}>
                <FaHome />
            </Button>
        </>
    )
}

export default AddItem

这是一个 CodeSandbox 的链接(可能与这里的有所不同,因为我在玩不同的东西):CodeSandbox

这是我最近尝试的控制台副本:

// the last console.log from handleInputChange shows an Object with the right data
object                                    // <= that's the typeof from handleInputChange
handleSubmit triggered
Inside handleSubmit Data: [object Object]
if() in handleSubmit triggered
Inside handleSubmit if() Data: [object Object]
Type: object Data: [object Object]        // <= from useEffect
executing POST
Inside if() Type: object Data: [object Object]
Type: undefined Data: undefined           // <= useEffect triggered by setSubmitted(false)
Error: "Request failed with status code 400"

日志记录似乎表明 inputs 状态从普通 JavaScript 对象转变为 handleSubmit 函数中的 [object Object],甚至在调用 if() 和/或 preventDefault() 之前,虽然我不能找出原因。这是handleSubmit()的代码:

const handleSubmit = event => {
        console.log("handleSubmit triggered")
        console.log(`Inside handleSubmit Data: ${inputs}`)
        if (event) {
            console.log("if() in handleSubmit triggered")
            console.log(`Inside handleSubmit if() Data: ${inputs}`)
            event.preventDefault()
            setSubmitted(true)
        }
}

我应该强调一下,我是一个相对较新的编程者,而且我不得不孤立地自学,所以我很害怕某个地方会出现明显的错误。尽管如此,我还是花了几个小时试图研究这个,甚至打电话给一个 React 开发者的朋友,他也被难住了。我尝试过如何调用handleSubmit,将其放入按钮中,或者通过onSubmit 将其通过箭头函数返回。我也尝试过在preventDefault 周围移动。似乎没有任何帮助。

我认为这与 Axios 无关,因为 inputs 在收到 POST 请求时已经是 undefined,但我将 Axios 作为标签放入,希望这可能是一个面向 Axios 的程序员都熟悉的 bug。

同样,通过 Postman 发出 POST 请求也很有效。

最后一件事:项目的后端是 .NET,所以我在 Visual Studio 上进行开发。我认为这可能是一些错误的 Visual Studio 行为,但在 CodeSandbox 之外运行代码会产生相同的错误,所以除非它是一些奇怪的格式化错误,否则在我谦虚和未受过教育的意见中,它似乎是别的东西。

有什么想法吗?

【问题讨论】:

  • 不要将对象放在console.log() 的字符串中,因为它会将它们转换为字符串,总是导致[object Object]。而是将其作为第二个参数传递或创建一个单独的日志:console.log('Data:', inputs)。这会误导你,我怀疑你的 inputs 很好,问题出在 axios 调用上。另外,分享您的代码和框。
  • @MrCode Aha - 我现在正在尝试。
  • 正如我所想 - 您的 inputs 没有任何问题。这是 axios 调用。也许您的 api 需要表单编码的 POST 数据而不是 json(axios 默认发送 json)。显示您所说的邮递员请求(哪些标头和哪些 POST 数据)。
  • @MrCode CodeSandbox 没有连接到后端,所以 Axios 必然会失败,不是吗?有没有办法让我在那个平台上连接一个 .NET 后端?我只是用它来显示inputs 哪里出错了。
  • 我对您的代码有几个要点,不分先后。我不会使用 useEffect 来调用 axios。关闭只会使您的生活复杂化。将默认数据添加到您的输入 useState,例如:useState({shape: '', size:'' ...})。状态设置是异步的。在设置状态时,您不会立即看到它的值。考虑改用 React Developer 工具。

标签: javascript reactjs post axios onsubmit


【解决方案1】:

这是解决问题的 cmets 的摘要:

像下面这样将对象传递到console.log() 的字符串中总是会导致显示[object Object],因为将其转换为字符串会导致怀疑对象属性在实际存在时发生了变化。

console.log(`Type: ${typeof inputs} Data: ${inputs}`);

改为使用第二个参数或进行单独的日志调用:

console.log(`Type: ${typeof inputs} Data:`, inputs);

之后,需要更正 POST 数据属性以确保大小写和类型与后端 API 匹配。

【讨论】:

    猜你喜欢
    • 2016-11-06
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 2022-01-05
    • 2020-11-11
    • 1970-01-01
    相关资源
    最近更新 更多