reactjs - React hooks:如何使用 useState() 更新嵌套对象的状态?
问题描述
我有这个表格,里面有我从后端得到的问题和答案,如下所示:
{
"id": 0,
"seq": 0,
"ccid": "string",
"topic": "string",
"riskOutcome": "string",
"condition": "string",
"comment": "string",
"visible": true,
"created": "2021-10-14T14:12:48.911Z",
"updated": "2021-10-14T14:12:48.911Z",
"createdById": 0,
"updatedById": 0,
"parentContentTypeId": 0,
"questionTypeId": 0,
"subContentTypes": [
{
"id": 0,
"seq": 0,
"ccid": "string",
"type": "string",
"topic": "string",
"riskOutcome": "string",
"condition": "string",
"comment": "string",
"visible": true,
"created": "2021-10-14T14:12:48.911Z",
"updated": "2021-10-14T14:12:48.911Z",
"createdById": 0,
"updatedById": 0,
"parentContentTypeId": 0,
"subContentTypes": [
null
],
"textI18Ns": [
{
"id": 0,
"text": "string",
"languageCode": "string",
"type": "string",
"contentTypeId": 0
}
]
}
],
"textI18Ns": [
{
"id": 0,
"text": "string",
"languageCode": "string",
"type": "string",
"contentTypeId": 0
}
]
}
subContentTypes 数组中是答案,而 textI18Ns 中是显示答案的文本。
我用这个将问题的答案分开
const [answerData, setAnswerData] = useState();
function getDatafromBackend = () =>{
dispatch(getOneQuestion(data))
.unwrap()
.then((originalPromiseResult) => {
var options = {};
Object.entries(originalPromiseResult.subContentTypes).map(([key, value]) => {
options[key] = value;
})
console.log("answertdata ", options)
setAnswerData(options);
}
}
现在我想做的是,从答案状态编辑文本。我的 JSX 看起来像这样:
let datalist = Object.entries(answerData).map(([key, value]) => {
return (<Paper elevation={3} style={{ margin: 10 }} key={"answerlist"+key}>
<Typography style={{ margin: 10}}>{"Daten zur Antwort: "}{answerData[key].ccid} </Typography>
{
Object.entries(answerData[key].textI18Ns).map(([index,value]) =>{
return (
<Paper elevation={3} style={{ margin: 10}} key={"questiontext"+index}>
<TextField label={"Text ID"} disabled className="QuestionDataField" value={answerData[key].textI18Ns[index].id} fullWidth></TextField><br />
<TextField label={"Content Typ ID"} disabled className="QuestionDataField" value={answerData[key].textI18Ns[index].contentTypeId} fullWidth></TextField><br />
<TextField label={"Typ"} className="QuestionDataField" value={answerData[key].textI18Ns[index].type} fullWidth onChange={(event) => { updateAnswerTexts(event, 'type', key, index) }}></TextField><br />
<TextField label={"Text"} multiline className="QuestionDataField" value={answerData[key].textI18Ns[index].text} fullWidth onChange={(event) => { updateAnswerTexts(event, 'text',key, index) }}></TextField><br />
<TextField label={"Sprache"} className="QuestionDataField" value={answerData[key].textI18Ns[index].languageCode} fullWidth onChange={(event) => { updateAnswerTexts(event, 'languageCode', key, index) }}></TextField><br />
<Divider/>
</Paper>
)
})
)}
setTableBody(datalist)
这是问题所在。我尝试了什么:制作一个副本,更改它并设置更改的对象
const updateAnswerTexts = (event,prop,key, index) =>{
let oldstate = answerData[index].textI18Ns[key];
let updatedstate = {...oldstate, [prop]: event.target.value};
let newstatetexts = Object.assign({}, answerData);
//Here is the Problem. Console says "Uncaught TypeError: 0 is read-only setSTate"
newstatetexts[index].textI18Ns[key] = updatedstate;
setAnswerData(newstatetexts)
setAnswerData((prevState) => {
prevState[index].textI18Ns[key] = updatedstate;
return({
...prevState
})
})
}
}
另一个尝试:控制台说,[prop] 是只读的
const updateAnswerTexts = (event,prop,key, index) =>{
setAnswerData((prevState) => {
prevState[index].textI18Ns[key][prop] = event.target.value;
return({
...prevState
})
})
}
另一个尝试:控制台说,[prop] 也是只读的
const updateAnswerTexts = (event,prop,key, index) =>{
let oldstate = answerData[index].textI18Ns[key];
let updatedstate = {...oldstate, [prop]: event.target.value};
setAnswerData((prevState) => {
prevState[index].textI18Ns[key] = updatedstate;
return({
...prevState
})
})
}
解决方案
这是为我做的
const updateAnswerTexts = (event,prop,key, index) =>{
let allanswers = {...answerTextsData};
let oneanwerobj = {...allanswers[key]};
let answertexts = {...oneanwerobj[index]}
answertexts[prop] = event.target.value;
oneanwerobj[index] = answertexts;
allanswers[key] = oneanwerobj
setAnswerTextsData(allanswers);
}
推荐阅读
- python - 在 python 中创建一个将用户输入字母添加到字典的程序
- vba - 在 vba 代码中保留页眉/页脚以进行文档拆分
- sql - Teradata:varchar 到时间戳
- python - clipspy:如何获取实例的插槽字典
- sql-server - 重复 SQL 查询并创建一个输出列
- python - Python:在 Numpy 数组中居中特征
- java - Spring Boot 池化数据库与多个数据库的连接
- javascript - 渲染函数不渲染任何东西 React Native
- python - 创建一个没有替换行的numpy矩阵
- c# - 如何将 ProcessModel 添加到 asp.net 核心 Web 应用程序