Welcome to our new site! Please share feedback

Hooks

useStore and useState

See the State section for more information on state handling.

useRef

Use the useRef hook to hold a reference to a rendered DOM element.

import { Show, useRef, useStore } from '@builder.io/mitosis';

export default function MyComponent() {
  const inputRef = useRef<HTMLInputElement>(null);

  const state = useStore({
    name: 'Steve',
    onBlur() {
      // Maintain focus
      inputRef.focus();
    },
    get lowerCaseName() {
      return state.name.toLowerCase();
    },
  });

  return (
    <div>
      <Show when={props.showInput}>
        <input
          ref={inputRef}
          css={{ color: 'red' }}
          value={state.name}
          onBlur={() => state.onBlur()}
          onChange={(event) => (state.name = event.target.value)}
        />
      </Show>
      Hello {state.lowerCaseName}! I can run in React, Vue, Solid, or Liquid!
    </div>
  );
}

Note: Don't name your useRef hook "ref" like const ref = useRef<HTMLInputElement>(null);. This would be a conflict with the ref from Vue.

forwardRef for React

In React you may need to wrap your component with forwardRef to provide direct access to an element (input for example). You can do this by using using a prop value as the ref

Mitosis input

export default function MyInput(props) {
  return <input ref={props.inputRef} />;
}

Mitosis output

import { forwardRef } from 'react';

export default forwardRef(function MyInput(props, inputRef) {
  return <input ref={inputRef} />;
});

useStyle

The useStyle hook can be used to add extra CSS to your component.

import { useStyle } from '@builder.io/mitosis';

export default function MyComponent(props) {
  useStyle(`
    button {
      font-size: 12px;
      outline: 1px solid black;
    }
  `);

  return (
    <button
      css={{
        background: 'blue',
        color: 'white',
      }}
      type="button"
    >
      Button
    </button>
  );
}

useStyle can also be used outside of the component's body:

import { useStyle } from '@builder.io/mitosis';

export default function MyComponent(props) {
  return <button type="button">Button</button>;
}

useStyle(`
  button {
    background: blue;
    color: white;
    font-size: 12px;
    outline: 1px solid black;
  }
`);

onInit

The onInit hook is the best place to put custom code to execute before the component mounts. It is executed before the onMount hook.

import { onInit, onMount } from '@builder.io/mitosis';

export default function MyComponent() {
  onInit(() => {
    alert('First: I have init!');
  });

  onMount(() => {
    alert('Second: I have mounted!');
  });

  return <div>Hello world</div>;
}

onMount

The onMount hook is the best place to put custom code to execute once the component mounts.

import { onMount } from '@builder.io/mitosis';

export default function MyComponent() {
  onMount(() => {
    alert('I have mounted!');
  });

  return <div>Hello world</div>;
}

onUnMount

The onUnMount hook is the best place to put any cleanup you need to do when a component is removed

import { onUnMount } from '@builder.io/mitosis';

export default function MyComponent() {
  onUnMount(() => {
    alert('I have been removed!');
  });

  return <div>Hello world</div>;
}

onUpdate

The onUpdate hook is the best place to put custom code that will either:

  • if no dependencies array is provided: execute on every render
  • if a non-empty dependencies array is provided: execute whenever any value in dependencies changes
import { onUpdate, useStore } from '@builder.io/mitosis';

export default function OnUpdateWithDeps() {
  const state = useStore({
    a: 'a',
    b: 'b',
  });

  onUpdate(() => {
    console.log('Runs on every update/rerender');
  });

  onUpdate(() => {
    console.log('Runs when a or b changes', state.a, state.b);
  }, [state.a, state.b]);

  return <div />;
}

useDefaultProps

The useDefaultProps hook sets default values for a component's props:

import { useDefaultProps } from '@builder.io/mitosis';

export default function Button(props) {
  useDefaultProps({
    text: 'default text',
    link: 'https://builder.io/',
    openLinkInNewTab: false,
    onClick: () => {
      console.log('hi');
    },
  });

  return (
    <div>
      <a href={props.link} target={props.openLinkInNewTab ? '_blank' : undefined}>
        {props.text}
      </a>
      <button onClick={(event) => props.onClick(event)} type="button">
        {props.buttonText}
      </button>
    </div>
  );
}

You can also use useDefaultProps outside of the component body:

import { useDefaultProps } from '@builder.io/mitosis';

useDefaultProps({
  text: 'default text',
});

export default function Button(props) {
  return <span>{props.text}</span>;
}

useTarget

The useTarget hook returns a variable or runs a function based on the target

Get variable based on target

import { useTarget, useStore } from '@builder.io/mitosis';

export default function MyName() {
  const state = useStore({
    get name() {
      const prefix = useTarget<string | number | boolean>({
        default: 'Default str',
        react: 123,
        angular: true,
        vue: 'v',
      });
      return prefix + 'foo';
    }
  });

  return (
    <div>{state.name}</div>
  );
}

default target is the fallback if the correct target can't be found in the object you pass into useTarget.

Run function based on target

import { onMount, useTarget } from '@builder.io/mitosis';

export default function MyLogger() {
     onMount(() => {
        useTarget({
          react: () => {
            console.log('react');
          },
          qwik: () => {
            console.log('qwik');
          },
          default: () => {
            console.log('the rest');
          },
        });
    });

  return <span></span>;
}