---
# System prepended metadata

title: 'Exploration of `const [x, setX] = useState()`'

---

# 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.

