我有一个由类别>字段构成的表单组件,然后每个字段有多个有效性行。我使用useState()跟踪表单值状态(每个字段ID的有效性行)。子组件中有一个添加按钮,可触发addValidityRowCallback
添加另一个有效性行。
我正在尝试更新状态并触发重新渲染,但它似乎不起作用。
import React, {useState} from 'react'
import CollapsibleFieldset from "../../fieldsets/CollapsibleFieldset";
import PersonInfoTypeFormRow from "./PersonInfoTypeFormRow";
import cloneAndUpdate from 'immutability-helper';
export default function PersonInfoForm({personInfoFormDataJson, webServiceAddress}) {
let [targetPersonId, formCategories, defaultFormValuesIndexedById] = parsePersonInfoJsonString(personInfoFormDataJson);
const [ formValuesById, setFormValues ] = useState(defaultFormValuesIndexedById);
const addValidityRowCallback = (personInfoTypeId) => {
let newEmptyRow = {id:12345, value:["NEW"], valueTitle:"","validityStartDate":"",createdDateTime:"",createdByPersonId:1212};
let newFormValuesState = cloneAndUpdate(formValuesById, {});
newFormValuesState[personInfoTypeId].push(newEmptyRow);
setFormValues(newFormValuesState);
};
return <form className="personInfoForm pure-form">
{formCategories.map((category) => {
return <CollapsibleFieldset key={category.id || category.title} legend={category.title}>
{category.personInfoTypes.map((personInfoType) => {
return <PersonInfoTypeFormRow {...personInfoType} key={personInfoType.id} addValidityRowCallback={addValidityRowCallback} values={formValuesById[personInfoType.id]}/>
})}
</CollapsibleFieldset>
})
{/* DEBUG........ */}
{Object.keys(formValuesById).map(fieldId => {
return formValuesById[parseInt(fieldId)].map(validityRow => {
return <h3 key={validityRow.id}>{validityRow.id}</h3>
})
})}
}
</form>;
}
我可以在调试器中看到正确调用了addValidityRowCallback
函数,克隆了现有状态,在结构中的正确位置添加了新行,然后将新状态传递回setFormValues()
但没有重新渲染?
更新:我已经解决了这个问题(尽管不能完全理解为什么我的原版不起作用),请在下面查看我的答案
答案 0 :(得分:0)
问题是您渲染formCategories
却将formValuesById
设置为状态。因此,如果在状态上保存formValuesById
,则需要保存formCategories
。
答案 1 :(得分:0)
好的,我通过cloneAndUpdate
(Hooks API Reference)方法而不是之后的方法更新对象来解决了此问题
assign[personInfoTypeId] = {$push:[newEmptyRow]};
let newPersonInfoTypeFieldsState = cloneAndUpdate(formValuesById,assign);
setFormValues(newFormValuesState);
我认为该库实际上不是在进行深层复制,而是重新使用结构的未更改部分,因此我怀疑稍后尝试手动更新实际上是在更新原始引用,从而做出新反应。设置状态时没有发现差异。使用库中记录的正确$push
语法对其进行了修复。