Infinte Loop on afterSetCellMeta

Tags: #<Tag:0x00007efc6d52f740> #<Tag:0x00007efc6d52eea8>

i am using version 14
i have a state in react
const [cellMeta, setCellMeta] = useState([]);
on afterSetCellMeta i call a function to insert the meta for the cells and i pass the state to handsontable cell

cell={
                rows.length && columns.length 
                ? cellMeta
                : undefined
            }

on doing so an infinte loop starts and i am not able to get the reason why,

Hi @guneetsinghtuli

Thank you for contacting us. Can you please share a code demo where the issue is replicable? It will be easier to debug it this way.

Hey @adrian.szymanski

You can find the code sandbox here https://codesandbox.io/p/devbox/p32xrg
I have added a comment on line 95

In order to replicate

  1. Open Console
  2. Click on any header and align it to any direction
  3. You will find a infinite loop which will eventually crash the application
  4. You can comment the line 95 cell={cellMeta} and perform the same in order to see the expected behaviour (it should trigger the function update the state and cell should acknowledge the updated state)

and Please let me know if I am missing on something with this

Hi @guneetsinghtuli

Thank you for the example. I checked it and followed your instructions but I don’t get any errors and sorting works fine. Can you please recheck it?

Hey @adrian.szymanski

You can have look at this screen recording

@guneetsinghtuli

Thank you for the recording. Now I am able to reproduce the issue. I think the reason for the error is explained quite well in the message itself:

Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn’t have a dependency array, or one of the dependencies changes on every render.

So, basically, there are too many updates within the logic you created and the results in an infinite loop.

Hey @adrian.szymanski

Currently in the code base I am only using useEffect to log the updates I can replicate the issue by removing that as well

So I am not sure if it’s the problem with my code logic or an actual issue with handsontable

  useEffect(() => {
    console.log("cellMeta", cellMeta);
  }, [cellMeta]);

@guneetsinghtuli

Maybe let’s change the approach here. Can you please tell me what is your expected result with the logic you have?

@adrian.szymanski

We have a case where the alignment or any css changes to any cell must persist but in order to persist we don’t use any local storage or session since for now we are using a react state

You can just assume it as a normal react state which will persist on reload, So whenever we make any changes to the alignment or any cell level change mostly css.
I saved the changes in a state and then pass it back to the handsontable so on reload as well you fill find the same alignment and css

I can’t use the default handsontable persistence state as I am in a restricted environment of iframe without access to local storage or any other

Hi @guneetsinghtuli

Thank you for the explanation. I did some more research and the reason for the loop is most likely due the fact that you are reading from the state in both cell option and afterSetCellData hook. Both of them will trigger re-rendering of the whole table and that will cause the infinite loop. In this case I would suggest to keep the logic and reading from state only to one of those methods.

Hey @adrian.szymanski

I do agree that can a possible explanation for infinite while loop, For My use case In order to save the UI change which user made like alignment or something I can apply the afterSetCellData hook and save it, But how can I apply the styling back later on after a reload if I can’t use the cell option is there any other parameter which I can use to pass back the last state of styling ?

@guneetsinghtuli

I’ll check the available options and update you after the weekend.

The reason you are encountering an infinite loop is because you are attempting to set the cell meta in the afterSetCellData hook. Unfortunately, I couldn’t get setState to work in useEffect. The only way I could get it to work was using a plain JS Map. Does this work for you:

https://codesandbox.io/p/devbox/handsontable-forked-9z845z

Hi @timeflys54321

Thank you for the suggestion. Let’s wait for @guneetsinghtuli confirmation if that helps.