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);

  };