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

React受控组件异常及状态值更新问题求助

问题分析与解决

问题根源

你的代码里settingValues函数更新状态时,没有合并原有状态对象。React的useState setter不会自动合并对象,每次调用setValues({[e.target.name]:e.target.value})时,新状态只包含当前修改的属性,其他原有属性(比如title、owner)都会被丢弃,变成undefined。

这会导致两个核心问题:

  • 其他输入框的value变为undefined,从受控组件转为非受控组件,触发Warning: A component is changing a controlled input to be uncontrolled...警告。
  • 状态对象丢失原有属性,出现“旧值与当前值并存”的异常表现(实际是部分属性被清空)。

解决方案

更新状态时,使用对象展开运算符保留原有状态的所有属性,仅覆盖当前修改的字段:

const settingValues=(e)=>{
    setValues({...values, [e.target.name]:e.target.value})
}

另外,select组件初始状态status为空字符串,但默认选项的value是"Status",会导致初始渲染时选项不匹配,建议调整默认选项的value为空字符串,和初始状态保持一致:

<option value="">status</option>

同时,useEffect的依赖可以更精准,只监听values.status而非整个values对象,避免不必要的重复触发:

useEffect(()=>{
    console.log(values.status)
}, [values.status])

修改后的完整代码

import React, { useState , useEffect } from "react";
import "./App.css";

function App() {
    const [values, setValues] = useState({
        title: "",
        owner: "",
        status: "",
        effort: "",
        due: ""
    })

    const settingValues=(e)=>{
        setValues({...values, [e.target.name]:e.target.value})
    }

    useEffect(()=>{
        console.log(values.status)
    }, [values.status])

    const style = { display:"flex",flexDirection:"column",padding: "5px",margin:"2px" }

    return (
        <div className="App" style={style}>
            <input type="text" name="title" value={values.title} onChange={(e)=>settingValues(e)} placeholder="title" style={style} />
            <input type="text" name="owner" value={values.owner} onChange={(e)=>settingValues(e)} placeholder="owner" style={style} />
            <select  name="status" value={values.status} onChange={(e)=>settingValues(e)}  style={style}>
                <option value="">status</option>
                <option value="New">New</option>
                <option value="Assigned">Assigned</option>
                {/* 注:原代码里的Assaigned拼写错误,已修正为Assigned */}
                <option value="Fixed">Fixed</option>
                <option value="Closed">Closed</option>
            </select>
            <input type="number" name="effort" value={values.effort} onChange={(e)=>settingValues(e)} placeholder="effort" style={style} />
            <input type="date" name="due" value={values.due} onChange={(e)=>settingValues(e)} style={style} />
        </div>
    );
}

export default App;

内容的提问来源于stack exchange,提问作者5C6 purushotham Reddy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 10:15:34