---
# System prepended metadata

title: A more general way to decompose functions in Qwik

---

# A more general way to decompose functions in Qwik

## Problem Description

Qwik gains its power by breaking a component into individual functions which can be lazy loaded. In order to do that Qwik places restrictions over what symbols a function is allowed to close over. This proposal relaxes the constrains so that a more free form code is accepted by Qwik. This work also lays path for `useEffect`-like API.

## Example

Developer writes (TypeScript):
```typescript=
import {qComponent, useState, onRender} from '@builder.io/qwik';

export const Buttons = [
  { label: '+', value: 1 },
  { label: '-', value: -1 },
]

const Counter = qComponent((props: {value?: number}) => {
  const state = useState({count: props.value || 0});
  
  onRender(() => (
    <>
      <span>{state.count}</span>
      {Buttons.map((btn) => (
        <button on:click={() => state.count += btn.value}>
          {btn.label}
        </button>
      ))}
    </>
  ));
});
```

Optimizer output (JavaScript):
```javascript=
import {qComponent, useState} from '@builder.io/qwik';
// imports for the compiler
import {captureRef, useClosure} from '@builder.io/qwik';

export const Counter_onMount = (props) => {
  const closure = useClosure();
  closure.state = useState({count: props.value || 0});
};

export const Counter_onRender = () => {
  const {state} = useClosure();
  return (
    <>
      <span>{state.count}</span>
      <button on:click={qHook('./foo.js#Counter_onClick', [state])}>+</button>
    </>
  );
}

export const Counter_onClick = () => {
  const {state} = useClosure();
  return state.count++;
}

const Counter = qComponent({
  onMount: qHook('./foo.js#Counter_onMount', 'Counter_onMount', [captureRef(0)]),
  onRender: qHook('./foo.js#Counter_onRender', 'Counter_onRender', [captureRef(0)]),
})
```

- `Q:` Why use `useClosure()` instead of assuming that it passed as argument?
  - `A:` Because we want to keep `qwikloader` simple and we don't want to have to teach it how to look for these arguments.
- `Q:` Without optimizer there is no way to control the variables captured by the closures.
  - `A:` In dev mode we will rely on the fact that we can run the `qComponent` creation multiple times, each generating a unique QRL. This will result in memory leak, but it should be good enough to run all of the tests.


# What changed
- `qHook` is only required to be generated by the Optimizer, not by developer.
- New set of marker functions for the Optimizer:
  - `qComponent`: Turn into `qComponent({onMount: qHook(...)})`
  - `onRender` (and friends): `qComponent({onRender: qHook(...)})`
  - Any `on:`/`onWindow:`/`onDocument:` property in JSX: `qHook(...)`