Javascript 一旦发生变化,反应就不会像我预期的那样起作用
为表指定此数据类型时,对象的对象数组:Javascript 一旦发生变化,反应就不会像我预期的那样起作用,javascript,reactjs,typescript,functional-programming,Javascript,Reactjs,Typescript,Functional Programming,为表指定此数据类型时,对象的对象数组: [ { "1": { "1": "Item s ", "2": "Manufacturer ", "3": "Mir s ", "4": "Decoription &qu
[
{
"1": {
"1": "Item s ",
"2": "Manufacturer ",
"3": "Mir s ",
"4": "Decoription ",
"5": "Contents ",
"6": "UOM ",
"7": "Total Ship Total Qty ",
"8": "% of Purohasec ",
"9": "Involoe Count ",
"10": "K Brand "
},
"2": {
"1": "fdsa ",
"2": "fdsa fdsa ",
"3": "16-fsd ",
"4": "fds fdsa TW fsda",
"5": "100 ",
"6": "B) ",
"7": "6 ",
"8": "0.17 ",
"9": "3 ",
"10": ""
},
},
....
]
我有一个显示要编辑的“行”的组件。我正在显示由json数据支持的表单和表(如上所述),认为我使用表并将其设置为状态,视图重新呈现并给出更改。上面的数据类型将采用上述格式,但标题、表数和字段都可能在不同的运行中发生变化。此外,我对数据类型没有太多控制权。作为道具传递的表是您在下面的cellChange中看到的TableCopy
const [tablesCopy, setTablesCopy] = useState<any>({});
但是,在显示器中,旧值没有被onChange事件替换,尽管在控制台中,我可以看到事件被正确的值触发
有没有更好地实施这一变革的建议,或者我应该采取的不同策略
编辑:添加我的useEffect初始化:
useEffect(() => {
const fetchData = async () => {
const path = "/tables.json";
const response = await fetch(path);
const tables: any = await response.json();
setTablesOrig(tables);
setTablesCopy({ ...tables });
const tableKeys = Object.keys(tablesCopy);
setNumOfTables(tableKeys.length);
};
fetchData();
}, []);
您应该克隆数据对象。如果您在表中仅使用
字符串
、数字
和布尔
,这应该可以正常工作:
const cellChange = (e: React.BaseSyntheticEvent) => {
const tt = tableTarget(e.target.id);
console.log("cellChange -> tt", tt);
var tables = JSON.parse(JSON.stringify(tablesCopy)); // <- clone
tables[tt.table][tt.row][tt.cell] = e.target.value;
setTablesCopy(tables);
};
在调用
setTableCopy
React之前,您正在对tablecopy
状态对象进行变异,发现setTableCopy
收到了它已经存储的相同实例,并且什么也不做。您应该创建对象的副本。@pilchard对不起,在我的使用效果中,我最初设置它:setTablesOrig(tables);setTablesCopy({…tables})
@AlexanderBurov我将我的初始化添加到了票证中,您可以将回调传递到setState
–setTablesCopy(prevTablesCopy=>prevTablesCopy[tt.table][tt.row][tt.cell]=e.target.value)
i使用lodash将其应用于初始集:setTablesCopy(uu.cloneDeep(tables))代码>我是否仍需要在cellChange方法中克隆它@AlexnderBurov@PompeyMagnus是的,这就是重点。React存储tablecopy
,当您调用settablecopy
时,它会检查它是否与它已有的实例相同。如果是这样,它将忽略更改,否则将重新渲染组件。另外,实际上,没有必要在初始设置中克隆它。
useEffect(() => {
const fetchData = async () => {
const path = "/tables.json";
const response = await fetch(path);
const tables: any = await response.json();
setTablesOrig(tables);
setTablesCopy({ ...tables });
const tableKeys = Object.keys(tablesCopy);
setNumOfTables(tableKeys.length);
};
fetchData();
}, []);
const cellChange = (e: React.BaseSyntheticEvent) => {
const tt = tableTarget(e.target.id);
console.log("cellChange -> tt", tt);
var tables = JSON.parse(JSON.stringify(tablesCopy)); // <- clone
tables[tt.table][tt.row][tt.cell] = e.target.value;
setTablesCopy(tables);
};
const cellChange = (e: React.BaseSyntheticEvent) => {
const tt = tableTarget(e.target.id);
console.log("cellChange -> tt", tt);
var tables = {
...tablesCopy,
[tt.table]: {
...tablesCopy[tt.table],
[tt.row]: {
...tablesCopy[tt.table][tt.row],
[tt.cell]: e.target.value
}
}
};
setTablesCopy(tables);
};