React does not update nested state using my setter

79 Views Asked by At

I'd like to update a react state (the "app" variable) object dynamically. The state has several properties, one of them is a nested object ("app.error" object). There is a kind of setter function ("setAppData") which takes any number of [existing key]: new value pairs of the state as parameter, create a new object and it should update the state according to "temp" object.

It works as intended when I want to update "app.error" using hard-coded variable or any other "app" properties, when I try to update the "app.error" using my setter function, it does not update.

const initialAppData: IAppData = {
  error: {} as IFrontEndError,
  interfaceTheme: UI_THEME.LIGHT,
};

function AppProvider(props: any) {
  const [app, setApp] = useState<IAppData>(initialAppData);

  useMemo(() => {
    window.addEventListener("error", (event) => {
      errorHandler({
        colno: event.colno,
        filename: event.filename,
        lineno: event.lineno,
        message: event.message,
      });
    });
  }, []);

  const errorHandler = (event: IFrontEndError) => setAppData({error: { ...event }});

  const setAppData = (newValue: TUpdateAppData) => {
    let key: keyof IAppData;
    let temp = getAppData();

    for (key in newValue) {
      if (
        !Object.prototype.hasOwnProperty.call(app, key) ||
        !Object.prototype.hasOwnProperty.call(newValue, key)
      )
        continue;
      temp = {
        ...temp,
        [key]: newValue[key],
      };
    }
    setApp({ ...temp, error: { ...temp.error } });
  };

  const getAppData = () => ({ ...app });

}

Using static update (it works as intended):

const setAppData = () => {
    let temp = getAppData();

    temp.error = {
      colno: 1,
      lineno: 1,
      message: "asd",
      filename: "asd"
    }

    setApp({ ...temp, error: { ...temp.error } });
  };

The structure of the "temp" objects before passing the spreaded copy to the state setter are exactly the same. "temp" object before spreading, triggered by event:

{
  "error": {
    "colno": 11,
    "filename": "http://127.0.0.1:5173/src/components/Debug.tsx?t=1667134926865",
    "lineno": 29,
    "message": "Error: asd"
  },
  "interfaceTheme": "light-theme"
}

getAppData() after error event:

{
  "error": {},
  "interfaceTheme": "light-theme"
}

"temp" object before spreading using hard-coded value:

{
  "error": {
    "colno": 1,
    "lineno": 1,
    "message": "asd",
    "filename": "asd"
  },
  "interfaceTheme": "light-theme"
}

getAppData() after execution using hard-coded value:

{
  "error": {
    "colno": 1,
    "lineno": 1,
    "message": "asd",
    "filename": "asd"
  },
  "interfaceTheme": "light-theme"
}

What is that I don't notice?

edit: sources of the project: https://github.com/gazsop/magus_shared https://github.com/gazsop/magus_react

0

There are 0 best solutions below