# Exploration of `const [x, setX] = useState()` [![hackmd-github-sync-badge](https://hackmd.io/dELoTgdNTvKklGl6TyUwkA/badge)](https://hackmd.io/dELoTgdNTvKklGl6TyUwkA) Would it be possible to have this syntax in Qwik? ```typescript= const Counter = qComponent(() => { const [count, setCount] = useState(0); return onRender(() => ( <button on:click={() => setCount(count+1)}> {count} </button> ); }); ``` ## Serialization The above would be transformed into: ```typescript= const Counter = qComponent(qrl('...', 'Counter_onMount')); export const Counter_onMount = () => { const [count, setCount] = useState(0); return onRender(qrl('...', 'Counter_onRender', [count, setCount])); }; export const Counter_onRender = () => { const [count, setCount] = useLexicalScope(); return ( <button on:click={qrl('...', 'Counter_onRender_click', [count, setCount])}> {count} </button> ); } export const Counter_onRender_click = () => { const [count, setCount] = useLexicalScope(); return setCount(count+1); }; ``` ### Can we serialize `count` and `setCount` The first issue to solve would need to be able to serialize `setCount`. This is hard because `setCount` is a function not data, however it could be done. When the setter is created it could be annotated with an `qStateId` which would point to the location of the state. ```typescript= function createStateSetter(state) { const stateSetter = function() { ... } stateSetter.qStateId = ...; // important bit. return stateSetter; } ``` So when we need to serialize it like here: `(qrl('...', 'Counter_onRender', [count, setCount])` it would result in: ```htmlembedded= <counter on:q-render="...#Counter_onRender[(qStateId)]"> ``` Where `qStateId` would come from the `stateSetter` and would look something like this. Assume the state object array is `abc123` and the value is stored at location `3`, then `qStateId` would be `abc123`, and we would add `()` to know it is setter. So the final HTML would be: ```htmlembedded= <counter on:q-render="...#Counter_onRender[(abc123.3)]"> ``` But we also need to serialize `count` which is a primitive hence it can't be wrapped in `Proxy` and therefore can't be tracked. Therefore the serialization would have to be as is. Assume that `count === 123` then: ```htmlembedded= <counter on:q-render="...#Counter_onRender[123, (abc123.3)]"> ``` The problem is that primitive values can be large and can be passed into many places. For example: ```htmlembedded= <counter on:q-render="...#Counter_onRender[123, (abc123.3)]"> <button on:click="...#Counter_onRender_click[123, (abc123.3)]"> 123 </button> </counter> ``` Notice that `123` is encoded multiple times in the output. If this was a string which was large this may become prohibitive as each listener will repeat the value. The other issue is that every time the `count` changes all of the attributes need to be updated. ## Conclusion 1. It is possible to serialize `const [x, setX] = useState()`. 2. The serialization is sub-optimal because `x` will likely be primitive and therefore serialized into each `on:*` listener multiple times. This is highly sub-optimal from both size as well as performance perspective. ## Recommendation We should not rule this out outright. But if our existing `Proxy` based API has the same name `useState` this may create conflict if we decide to implement this approach. For this reason we should rename `useState` to `useQState` to differentiate the semantics behavior difference and keep `useState` API open in case we decide to implement existing semantics.