Given an integer id "tid" and a grid named "tasks" with numeric columns "id" and "state", you should be able to toggle a state cell like so:
tasks.value:update state:!state where id=tid from tasks.value
If you're seeing odd behavior, I'd recommend confirming that the "state" and "id" columns of your grid actually contain numbers, and not strings; you can see this distinction more easily if you inspect the table via the listener; strings in cells will be enclosed in double-quotes:

If you set the grid's format string appropriately, (in the above example "isi" for an integer column, a string column, and an integer column) you can "re-normalize" the data in a grid by toggling between JSON and CSV editing mode in the grid's properties dialog.
It may be a little surprising that negating the string "0" with ! produces the number 0, instead of 1, but this is because ! is not an arithmetic operator, it is a logical one, and all non-empty strings are considered "truthy" in Lil:
!(nil,"","0","1",0,1) # (1,1,0,0,1,0)
If you're ever wanting the logical negation of a grid column that may contain "0"/"1" strings, you could also resolve the issue by adding zero to the string first, coercing it to a number:
0+(nil,"","0","1",0,1) # (0,0,0,1,0,1) !0+(nil,"","0","1",0,1) # (1,1,1,0,1,0)
Or, in this context,
tasks.value:update state:!0+state where id=tid from tasks.value
Does that help?