Props

Use props to pass data into the child component. Props are declared as named arguments to the OnMount function.

In this example a component Item declares optional name, quantity, description, and price.

const Item = component$((props: {
   name?: string,
   quantity?: number,
   description?: string,
   price?: number
  }) => {
    return ...;
  }
);

The resulting component can be used like so:

const MyApp = component$(() => {
  return (
    <>
      - With no props: <Item/>
      - With some props: <Item description="Item description"/>
      - With all props: <Item name="Hammer"
                             quantity={3}
                             description="Best organic hammer"
                             price={10.00} />
    </>
  );
});

Type information

Using TypeScript, the props type information correctly flows into the component.

interface ItemProps {
  name?: string,
  quantity?: number,
  description?: string,
  price?: number
};


const Item: JSXNode<ItemProps> = component$((props: ItemProps) => {
  return ...;
});

Notice that Item is of type JSXNode<ItemProps>, which constraints the <Item /> usage to only declared properties. (<Item foo="bar"/> would produce a type error as foo is not part of the Item's props.)

It is possible to extract the type interface from the Item using PropsOf.

const props: PropsOf<Item> = {
  name: 'Item',
  ...
};

Serialization

Qwik components can render out of order. A component can render without forcing a parent component to render first or to force child components to render as a consequence of the component render. This is an important property of Qwik because it allows Qwik applications to only re-render components which have been invalidated due to state change rather than re-rendering the whole component tree on change.

When components render, they need to have access to their props. Parent components create props. The props must be serializable for the component to render independently from the parent. (See serialization for an in-depth discussion on what is serializable.)

Invalidating child components

When re-rendering a component, the child component props can stay the same or be updated. A child component only invalidates if the child component props change.

const Child = component$((props: { count: number }) => {
  return (
    <span>{props.count}</span>
  );
});

const MyApp = component$(() => {
  const store = useStore({ a: 0, b: 0, c: 0 });

  return (
    <>
      <button onClick$={() => store.a++}>a++</button>
      <button onClick$={() => store.b++}>b++</button>
      <button onClick$={() => store.c++}>c++</button>
      {JSON.stringify(store)}

      <Child count={store.a} />
      <Child count={store.b} />
    </>
  );
});

In the above example, there are two <Child/> components.

  • Every time a button is clicked, one of the three counters is incremented. A change of counter state will cause the MyApp component to re-render on each click.
  • If store.c has been incremented, none of the child components get re-render. (And therefore, their code does not get lazy-loaded.)
  • If store.a has been incremented than only <Child count={store.a}/> will re-render.
  • If store.b has been incremented than only <Child count={store.b}/> will re-render.

Notice that the child components only re-render when their props change. This is an important property of Qwik applications as it significantly limits the amount of re-rendering the application must do on state change. While less re-rendering has performance benefits, the real benefit is that large portions of the applications do not get downloaded if they don't need to be re-rendered.