Hooks

useStore()

Creates an object that Qwik can track across serializations.

Use useStore to create a state for your application. The returned object is a proxy that has a unique ID that is used in QRLs to refer to the store.

Example

Example showing how useStore is used in Counter example to keep track of the count.

const Stores = component$(() => {
  const counter = useCounter(1);
  // Reactivity happens even for nested objects and arrays
  const userData = useStore({
    name: 'Manu',
    address: {
      address: '',
      city: ''
    },
    orgs: []
  });
  // useStore() can also accept a function to calculate the initial value
  const state = useStore(() => {
    return {
      value: expensiveInitialValue()
    }
  })
  return (
    <Host>
      <div>Counter: {counter.value}</div>
      <Child userData={userData} state={state}/>
    </Host>
  )
});
function useCounter(step: number) {
  // Multiple stores can be created in custom hooks for convenience and composability
  const counterStore = useStore({
    value: 0
  });
  useClientEffect$(() => {
    // Only runs in the client
    const timer = setInterval(() => {
      counterStore.value += step;
    }, 500);
    return () => {
      clearInterval(timer);
    };
  });
  return counterStore;
}

useRef()

A very thin wrapper around useStore() including the proper type signature to be passed to the ref property in JSX.

export function useRef<T = Element>(current?: T): Ref<T> {
  return useStore({ current });
}

Example

const Cmp = component$(() => {
  const input = useRef<HTMLInputElement>();
  useClientEffect$((track) => {
    const el = track(input, 'current')!;
    el.focus();
  });
  return (
    <Host>
      <input type="text" ref={input}/>
    </Host>
  )
});

useWatch$()

Reruns the watchFn when the observed inputs change.

Use useWatch to observe changes on a set of inputs, and then re-execute the watchFn when those inputs change.

The watchFn only executes if the observed inputs change. To observe the inputs use the obs function to wrap property reads. This creates subscriptions that will trigger the watchFn to re-run.

Example

The useWatch function is used to observe the state.count property. Any changes to the state.count cause the watchFn to execute which in turn updates the state.doubleCount to the double of state.count.

const Cmp = component$(() => {
  const store = useStore({
    count: 0,
    doubleCount: 0,
    debounced: 0
  });
  // Double count watch
  useWatch$((track) => {
    const count = track(store, 'count');
    store.doubleCount = 2 * count;
  });
  // Debouncer watch
  useWatch$((track) => {
    const doubleCount = track(store, 'doubleCount');
    const timer = setTimeout(() => {
      store.debounced = doubleCount;
    }, 2000);
    return () => {
      clearTimeout(timer);
    };
  });
  return (
    <Host>
      <div>{store.count} / {store.doubleCount}</div>
      <div>{store.debounced}</div>
    </Host>
  )
});

useClientEffect$()

const Timer = component$(() => {
  const store = useStore({
    count: 0
  });
  useClientEffect$(() => {
    // Only runs in the client
    const timer = setInterval(() => {
      store.count++;
    }, 500);
    return () => {
      clearInterval(timer);
    };
  });
  return (
    <Host>
      {store.count}
    </Host>
  )
});

useMount$()

Register a hook that executes on component creation. useMount$() will block the rendering of the component until after useMount$() callback resolves. (This is useful for fetching asynchronous data and delaying rendering until data is received, ensuring that the rendered component contains the data.).

While useMount$() executes both on the server and on the client, it runs exactly once. (Either on the server or on the client depending on where the component got first rendered.)

See also: useServerMount$() that have same semantics but only run on server.

Example

const Cmp = component$(() => {
  const store = useStore({
    users: []
  });
  useMount$(async () => {
    // This code will run on component creation to fetch the data.
    store.users = await db.requestUsers();
  });
  return (
    <Host>
      {store.users.map((user => (
        <User user={user}/>
      )))}
    </Host>
  )
});

interface User {
  name: string;
}

function User(props: {user: User}) {
  return (
    <div>Name: {props.user.name}</div>
  )
}

useServerMount$()

Registers a server mount hook that runs only in the server when the component is first mounted.

Example

const Cmp = component$(() => {
  const store = useStore({
    users: []
  });
  useServerMount$(async () => {
    // This code will ONLY run once in the server, when the component is mounted
    store.users = await db.requestUsers();
  });
  return (
    <Host>
      {store.users.map((user => (
        <User user={user}/>
      )))}
    </Host>
  )
});

interface User {
  name: string;
}

function User(props: {user: User}) {
  return (
    <div>Name: {props.user.name}</div>
  )
}

useHostElement()

Retrieves the Host Element of the current component.

NOTE: useHostElement method can only be used in the synchronous portion of the callback (before any await statements.)

const Section = component$(() => {
  const hostElement = useHostElement();
  console.log(hostElement); // hostElement is a HTMLSectionElement
  return (
    <Host>
      I am a section
    </Host>
  )
}, {
  tagName: 'section'
});

useStyles$()

A lazy-loadable reference to component's styles.

Component styles allow Qwik to lazy load the style information for the component only when needed. (And avoid double loading it in case of SSR hydration.)

import styles from './code-block.css?inline';
export const CmpStyles = component$(() => {
  useStyles$(styles);
  return <Host>Some text</Host>;
});
Made with ♡ by the Builder.io team