简体   繁体   English

由提交功能改变的反应表单状态

[英]React form state mutated by submit function

I'm teaching myself React, and building a small single-page React app with an Axios API.我正在自学 React,并使用 Axios API 构建一个小型的单页 React 应用程序。 I have a POST request that keeps on failing.我有一个不断失败的 POST 请求。 Extensive use of console.log seems to indicate that the state of the form inputs is somehow getting changed by the submit function, though I can't figure out why. console.log广泛使用似乎表明表单输入的状态正在以某种方式被提交函数改变,尽管我不知道为什么。 Help!帮助!

Here's the code:这是代码:

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

Here's a link to a CodeSandbox (which may be a bit different than what is here, as I play around with different things): CodeSandbox这是 CodeSandbox 的链接(可能与此处的内容略有不同,因为我在玩不同的东西): CodeSandbox

And here's a copy of the console from my most recent attempt:这是我最近尝试的控制台副本:

// 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"

The logging seems to indicate that the inputs state mutates from a normal JavaScript object to [object Object] in the handleSubmit function, even before the if() and/or preventDefault() are called, though I can't figure out why.日志记录似乎表明,即使在preventDefault() if()和/或preventDefault()之前,handleSubmit 函数中的inputs状态从普通 JavaScript 对象突变为 [object Object],但我不知道为什么。 Here's the code of handleSubmit() again:再次是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)
        }
}

I should probably emphasize that I'm a relative newcomer to programming, and I've had to teach myself pretty much in isolation, so I'm pretty scared that there's an obvious mistake somewhere.我可能应该强调一下,我是编程的新手,而且我不得不孤立地自学,所以我很害怕某处有明显的错误。 Still, I've spent a couple of hours trying to research this, and even called a friend who's a React developer, and he was stumped too.尽管如此,我还是花了几个小时试图研究这个,甚至打电话给一个 React 开发人员,他也被难住了。 I've tried playing around with how handleSubmit is called, putting it in the button, or having it returned by an arrow function by onSubmit .我已经尝试过如何handleSubmit ,将它放在按钮中,或者让它由onSubmit的箭头函数返回。 I've also tried moving around the preventDefault .我也试过在preventDefault周围移动。 Nothing seems to help.似乎没有任何帮助。

I don't think this has what to do with Axios, as the inputs are already undefined by the time they get to the POST request, but I put in Axios as a tag hoping that this may be a bug Axios-oriented programmers are familiar with.我不认为这与 Axios 有什么关系,因为在它们到达 POST 请求时inputs已经undefined ,但是我将 Axios 作为标记放入希望这可能是面向 Axios 的程序员所熟悉的错误和。

Similarly, making the POST request through Postman works like a charm.同样,通过 Postman 发出 POST 请求也很有魅力。

One final thing: the backend for the project is .NET, so I'm developing on Visual Studio.最后一件事:项目的后端是 .NET,所以我在 Visual Studio 上进行开发。 I thought this might some buggy Visual Studio behavior, but running the code out of CodeSandbox creates the same bug, so unless it's some weird formatting bug that carried over, it seems to be something else, in my humble and uneducated opinion.我认为这可能是一些有缺陷的 Visual Studio 行为,但是在 CodeSandbox 之外运行代码会产生相同的错误,所以除非它是一些奇怪的格式错误,否则它似乎是其他东西,在我谦逊和未受过教育的观点中。

Any ideas?有任何想法吗?

This is a summary of the comments which solved the problem:这是解决问题的评论的摘要:

Passing an object into the string for console.log() like below always results in showing [object Object] due to casting it as a string which lead to suspecting that the object properties are mutated when they were actually present.像下面这样将对象传递到console.log()的字符串中总是会导致显示[object Object]因为将其转换为字符串,这会导致怀疑对象属性在它们实际存在时发生了变异。

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

Instead, use the second argument or do a separate log call:相反,使用第二个参数或执行单独的日志调用:

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

After that it was a case of correcting the POST data properties to make sure the casing and types matched up with the backend API.之后是更正 POST 数据属性以确保大小写和类型与后端 API 匹配的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM