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>;
}
