渲染文本输入后使用 useState Hook 更新对象

Updating object with useState Hook after rendering text input

我正在为我们公司构建调试清单应用程序的早期过程。由于清单相当大(其中很多),我想创建一个映射对象的函数,并在渲染写入的值后使用 useState Hook 更新适当的状态。

页面正在呈现,没有任何问题。只有在输入更改后才会出现此问题。而不是更新对象中的正确状态。看起来逻辑是在我的对象中添加一个额外的部分并创建另一个输入元素。

import React, { useState } from 'react'


const ProjectInfo = () => {

  const _renderObject= () => {
     return Object.keys(answers).map((obj, i) => {
        return(
            <div key={obj}>
                <label>{answers[obj].question}</label>
                <input type="text" onChange={(e, obj) => setAnswer(
                    {
                    ...answers,
                    obj:{
                       value: e.target.value
                    }})} />    
            </div>
        )
    })
}

const [answers, setAnswer] = useState({
    11:{
        question:"Project Name",
        value:""
    },
    12:{
        question:"Project Number",
        value:"" 
    }
})

    return(
        <div>
            <section>
                {_renderObject()}
            </section>
            <p>{`Project Number is: ${answers[11].value}`}</p>
            <p>{`Project Name is: ${answers[12].value}`}</p>
        </div>
    )
}

export default ProjectInfo

我原以为状态会正常更新。但是我怀疑在我的 renderObject 方法中,我的 .map 函数的 obj 变量没有在我的 setAnswer 函数中使用,并导致使用 "obj".

键名创建另一个字段

如果这是问题所在,是否可以让我的 renderObject 方法中的 setAnswer 函数使用 map 函数的 "obj" 值而不是单词 obj 的实际值作为键?

如果不是,解决这个问题的最佳方法是什么?我正在考虑在屏幕底部添加一个提交按钮并使用 onClick 事件侦听器更新所有状态。但现在我想我会遇到同样的问题,因为 obj 变量的范围没有解决。

如有任何帮助,我们将不胜感激。我只做了几个月,任何建议和反馈也将不胜感激!

onChange={(e, obj) => setAnswer(
                    {
                    ...answers,
                    obj:{
                       value: e.target.value
                    }})}

您在这里传播答案并添加另一个具有目标值的对象。这就是问题所在。希望你明白这一点。

试试这个

onChange={
  (e, obj) => {
    const updatedAnswer = answer.map(ans => ans.question === obj.question ? {...ans,value: e.target.value }:ans)
    setAnswer(
      {
        ...updatedAnswer
      }
    )
  }
} 

BW 您的对象应该包含密钥的正确 ID。

您在更新状态时似乎没有正确使用动态密钥。您还需要更新密钥中的值而不是覆盖它。另外 obj 不应该是 onChange 的第二个参数,而必须从封闭范围

接收
const _renderObject= () => {
     return Object.keys(answers).map((obj, i) => {
        return(
            <div key={obj}>
                <label>{answers[obj].question}</label>
                <input type="text" onChange={(e) => setAnswer(
                    {
                    ...answers,
                   [obj]:{
                       ...answers[obj],
                       value: e.target.value
                    }})} />    
            </div>
        )
    })

这是因为您没有正确更新键,您需要在输入 onchange 回调中传递 obj,因为它会产生另一个引用,而不是映射数组 (obj)。所以在你的情况下 obj 是未定义的。这是工作代码:

const _renderObject = () => {
    return Object.keys(answers).map((obj, i) => {
      return (
        <div key={obj}>
          <label>{answers[obj].question}</label>
          <input
            type="text"
            onChange={e =>

              setAnswer({
                ...answers,
                [obj]: {   //take obj
                  ...answers[obj],//keep specific object question
                  value: e.target.value//change only specfic object value
                }
              })
            }

          />
        </div>
      );
    });
  };

这里正在工作url:https://codesandbox.io/s/hardcore-pike-s2hfx