Welcome to our new site! It's WIP :)

Gotchas and limitations

We have put together ESLint rules that will warn you when encountering these limitations (and many more). The rules themselves are a great source of documentation. Make sure to read up on them here

Defining variables with the same name as a state property will shadow it

Mitosis input

export default function MyComponent() {
  const state = useStore({
    foo: 'bar',

    doSomething() {
      const foo = state.foo;
    },
  });
}

Mitosis output

import { useState } from 'react';

export default function MyComponent(props) {
  const [foo, setFoo] = useState(() => 'bar');
  function doSomething() {
    const foo = foo;
  }

  return <></>;
}

Work around

Use a different variable name

Mitosis input

export default function MyComponent() {
  const state = useStore({
    foo: 'bar',

    doSomething() {
      const foo_ = state.foo;
    },
  });
}

Mitosis output

import { useState } from 'react';

export default function MyComponent(props) {
  const [foo, setFoo] = useState(() => 'bar');
  function doSomething() {
    const foo_ = foo;
  }

  return <></>;
}

Async methods can't be defined on "state"

Mitosis input

export default function MyComponent() {
  const state = useStore({
    async doSomethingAsync(event) {
      //  ^^^^^^^^^^^^^^^^^^^^^^^^^
      //  Fails to parse this line
      return;
    },
  });
}

Work around

You can either:

a. Use promises in this context instead or b. Use an immediately invoked async function

Mitosis input

export default function MyComponent() {
  const state = useStore({
    doSomethingAsync(event) {
      void (async function () {
        const response = await fetch(); /* ... */
      })();
    },
  });
}

Mitosis output

import { useState } from 'react';

export default function MyComponent(props) {
  function doSomethingAsync(event) {
    void (async function () {
      const response = await fetch();
    })();
  }

  return <></>;
}

Functions can't be passed by reference to JSX callbacks

Mitosis input

export default function MyComponent() {
  const state = useStore({
    myCallback(event) {
      // do something
    },
  });

  return <input onClick={state.myCallback} />;
}

Mitosis output

import { useState } from 'react';

export default function MyComponent(props) {
  function myCallback(event) {
    // do something
  }

  return (
    <>
      <input
        onClick={(event) => {
          myCallback;
        }}
      />
    </>
  );
}

Work around

Define an anonymous function in the callback

Mitosis input

export default function MyComponent() {
  const state = useStore({
    myCallback(event) {
      // do something
    },
  });

  return <input onClick={(event) => state.myCallback(event)} />;
}

Mitosis output

import { useState } from 'react';

export default function MyComponent(props) {
  function myCallback(event) {
    // do something
  }

  return (
    <>
      <input
        onClick={(event) => {
          myCallback(event);
        }}
      />
    </>
  );
}

Can't assign "params" to "state"

JSX lite parsing fails on referencing props in a call to useState.

Mitosis input

export default function MyComponent(props) {
  const state = useStore({ text: props.text });
  //                             ^^^^^^^^^^
  //                             Could not JSON5 parse object
}

Work around

Use onMount:

Mitosis input

export default function MyComponent(props) {
  const state = useStore({ text: null });

  onMount(() => {
    state.text = props.text;
  });
}

Mitosis output

import { useState } from 'react';

export default function MyComponent(props) {
  const [text, setText] = useState(() => null);

  useEffect(() => {
    setText(props.text);
  }, []);

  return <></>;
}

Can't assign function output to "state"

JSX lite parsing fails if a state value isn't valid JSON

If the initial state value is a computed value (whether based on props or the output of some function), then you cannot inline it. Instead, use a getter method:

Mitosis input

import { kebabCase } from 'lodash';

export default function MyComponent(props) {
  const state = useStore({
    name: kebabCase('Steve'),
    //    ^^^^^^^^^
    //    Could not JSON5 parse object
  });

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

Work around

Use a getter method:

Mitosis input

import { kebabCase } from 'lodash';

export default function MyComponent(props) {
  const state = useStore({
    get name() {
      return kebabCase('Steve');
    },
  });

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

Mitosis output

import { kebabCase } from 'lodash';

export default function MyComponent(props) {
  function name() {
    return kebabCase('Steve');
  }

  return (
    <div>
      <h2>
        Hello,
        {name()}
      </h2>
    </div>
  );
}

Can't destructure assignment from state

Destructuring assignment from state isn't currently supported, and is ignored by the compiler.

Mitosis input

export default function MyComponent() {
  const state = useStore({ foo: '1' });

  onMount(() => {
    const { foo } = state;
  });
}

Mitosis output

import { useState } from 'react';

export default function MyComponent(props) {
  const [foo, setFoo] = useState(() => '1');

  useEffect(() => {
    const { foo } = state;
  }, []);

  return <></>;
}

Work around

Use standard assignment instead for now.

Mitosis input

export default function MyComponent() {
  const state = useStore({ foo: '1' });

  onMount(() => {
    const foo = state.foo;
  });
}

Mitosis output

import { useState } from 'react';

export default function MyComponent(props) {
  const [foo, setFoo] = useState(() => '1');

  useEffect(() => {
    const foo = foo;
  }, []);

  return <></>;
}

Can't set default props value with destructuring

Setting default props value with destructuring isn't currently supported, and is ignored by the compiler.

Mitosis input

export default function MyComponent({ color = 'blue' }) {
  return <div>{color}</div>;
}

Mitosis output

export default function MyComponent(props) {
  return <div>{color}</div>;
}

Work around

define a local variable

Mitosis input

const DEFAULT_VALUES = {
  color: 'blue',
};
export default function MyComponent(props) {
  return <div>{props.color || DEFAULT_VALUES.color}</div>;
}

Mitosis output

const DEFAULT_VALUES = {
  color: 'blue',
};
export default function MyComponent(props) {
  return <div>{props.color || DEFAULT_VALUES.color}</div>;
}

Can't destructure props as ...rest

...rest props parameter isn't currently supported

Mitosis input

export default function MyComponent({ children, ...rest }) {
  return <div {...rest}>{children}</div>;
}

Mitosis output

export default function MyComponent(props) {
  return <div {...rest}>{props.children}</div>;
}