You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中fetch获取数据后如何设置初始state值来更新表单?

问题根因

  • 你用了defaultValue实现非受控输入框,这个属性只在组件首次渲染时生效,你的接口请求是组件渲染后才触发的,拿到数据后defaultValue不会更新,所以未手动修改的字段对应的状态一直是初始的undefined。
  • 同时你维护了两套冗余状态:data存储接口返回的原始数据,单独的title/desc/author存储表单值,两者没有做同步,未修改的字段状态一直停留在初始的空值。

修复方案

直接复用data作为表单的受控状态,不需要单独维护三个字段的状态,修改后代码如下:

import React, { useState, useEffect } from "react"
import { useParams, useHistory } from "react-router-dom"

const EditBlog = () => {
    const { id } = useParams()
    const history = useHistory()
    // 初始化状态对应字段,避免首次渲染报undefined错
    const [data, setData] = useState({
        title: "",
        desc: "",
        author: ""
    })

    useEffect(() => {
        fetch('http://localhost:8000/values/' + id)
            .then((res) => res.json())
            .then((resData) => {
                setData(resData)
            })
    }, [id])

    const updateHandler = (e) => {
        e.preventDefault()
        const updatedBlog = { 
            title: data.title, 
            desc: data.desc, 
            author: data.author 
        }
        fetch('http://localhost:8000/values/' + id, {
            method: "PUT",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            },
            body: JSON.stringify(updatedBlog)
        })
        .then(() => {
            console.log(updatedBlog)
            history.push("/")
        })
    }

    // 统一处理输入框变更,减少重复代码
    const handleInputChange = (field) => (e) => {
        setData(prev => ({
            ...prev,
            [field]: e.target.value
        }))
    }

    return (
        <React.Fragment>
            <div>
                <h1>Edit Blog</h1>
                <form onSubmit={updateHandler} className="new-blog">
                    <label>Blog Title</label>
                    <div className="input-box">
                        <input
                            onChange={handleInputChange('title')}
                            type="text"
                            value={data.title}
                            className="inputField"
                        />
                    </div>

                    <label>Blog Body</label>
                    <div className="input-box">
                        <textarea
                            onChange={handleInputChange('desc')}
                            cols="64"
                            value={data.desc}
                        />
                    </div>

                    <label>Blog Author</label>
                    <div className="input-box">
                        <input
                            onChange={handleInputChange('author')}
                            className="inputField"
                            type="text"
                            value={data.author}
                        />
                    </div>
                    <button>Save</button>
                </form>
            </div>
        </React.Fragment>
    )
}

export default EditBlog

修改说明

  • 给data状态初始化了对应字段的空值,避免组件首次渲染时输入框value为undefined的报错
  • 把原来的非受控输入框改成受控输入框,用value绑定data对应字段,接口返回数据后会自动同步填充到输入框
  • 新增了通用的handleInputChange方法处理所有输入框的变更,减少重复代码
  • 提交时直接从data取所有字段值,未修改的字段也会保留接口返回的初始值,不会出现undefined的问题

内容的提问来源于stack exchange,提问作者UN_1032

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 11:39:05