我正在为我们的公司构建调试清单应用程序的早期阶段。由于清单很大(其中许多清单),因此我想创建一个映射到对象的函数,并且在渲染所编写的值之后,将使用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变量的范围没有解决。
任何帮助将不胜感激。我只做了几个月,任何建议和反馈也将不胜感激!
答案 0 :(得分:3)
您似乎在更新状态时未正确使用动态键。另外,您需要更新键中的值,而不要覆盖它。此外,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>
)
})
答案 1 :(得分:0)
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
}
)
}
}
您的对象应包含该密钥的属性ID。
答案 2 :(得分:0)
这是因为您没有正确更新键,并且需要在输入onchange回调中传递obj,因为它会提供另一个引用,而不是映射的array(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>
);
});
};