React useState 将用户输入存储在对象中

React useState storing user input in an object

我正在尝试使用将其值保存到单个状态对象中的多组无线电输入来构建表单。

我在使用以下代码时遇到的问题是状态正在正确更新,但是单选检查属性和两个段落标签没有重新呈现以显示新文本。如果我使用其他方法重新渲染组件,那么文本会更新以匹配状态。

我知道在一个理想的世界中我会为每个无线电组都有一个 useState(),但是用于生成表单的数据是来自服务器的动态数据所以我无法预测状态的形状看起来像我需要将输入作为对象发送回服务器。我已经简化了示例,但问题是一样的...

import { useState } from 'react'

const Form = () => {

    const [ data, setData ] = useState({});

    const handleChange = (key, value) => {
        data[key] = value
        setData(data)
    }

    return (
        <div>
            <h2>Form</h2>

            <p>Gender: { data.gender }</p>
            <p>Age: { data.age }</p>

            <form action="">
                <label>
                    Male
                    <input type="radio" name="gender" checked={data['gender'] === 'male'} onChange={() => handleChange('gender', 'male')} />
                </label>
                <label>
                    Female
                    <input type="radio" name="gender" checked={data['gender'] === 'female'}  onChange={() => handleChange('gender', 'female')} />
                </label>
                <label>
                    Old
                    <input type="radio" name="age" checked={data['age'] === 'old'}  onChange={() => handleChange('age', 'old')} />
                </label>
                <label>
                    Young
                    <input type="radio" name="age" checked={data['age'] === 'young'}  onChange={() => handleChange('age', 'young')} />
                </label>
            </form>
        </div>
    );
}

export default Form;

我对反应还比较陌生,所以非常感谢任何帮助,我确信这是很明显的我遗漏的东西!

您只是在更新数据对象中的键,因此对象本身将保持其原始引用。这不会导致 re-render 因为实际状态,data 对象没有改变。

要让组件在状态更新时呈现,您可以执行 setData({...data, [key]: value});

我想我看到了问题。

data[key] = value

在这里,您直接将状态静音。相反,尝试像

const newData ={};
newData[key] = value;
setData(newData);

当您按自己的方式执行 setData 时,它会发现数据已经相同,因此不会更新任何内容。

const handleChange = (key, value) => {
        
        setData({...data, key : value})
    }

只是改变这个

const [ data, setData ] = useState({});

const handleChange = (key, value) => {
    setData({...data, [key]: value});
}