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
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
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
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 });
// ^^^^^^^^^^
// Error
}
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'),
// ^^^^^^^^^
// Error
});
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>;
}