mitosis
mitosis copied to clipboard
BUG: useState hook "set" functions break within onUpdate hook (non-React)
Scope
- [x] This only impacts specific generators/outputs (please list them here): svelte
Describe the bug
When using useState in your builder or in my project, angular is not rendering the correct code.
To Reproduce Steps to reproduce the behavior:
- Create a useState with get and set.
- OnUpdate call to the setter.
- Angular will generate this code, where
setNamedoes not exist.
A link to a https://mitosis.builder.io/ fiddle containing the bug:
Expected behavior When using a setter should work.
Additional context I've oppened this to talk about angular but I can see the same in all the libraries except with react, is use state only compatible with react??
update: see https://github.com/BuilderIO/mitosis/issues/425#issuecomment-1145644830
@CKGrafico ~~Our Fiddle examples are actually using an outdated syntax of useState. Let me quickly update those to better reflect how you'd use useState today!~~
The useState hook example you showed should work for all frameworks! You happen to have uncovered a bug in how we transform state-setting logic within hooks.
I actually misspoke: The useState hook example you showed should work for all frameworks! You happen to have uncovered a bug in how we transform state-setting logic within hooks.
Here is a look at another useState syntax from examples in our docs, which uses SolidJS-like mutation to alter state: https://github.com/BuilderIO/mitosis/blob/main/docs/components.md#state
This syntax works fine at the moment. Your example would look something like this
Feel free to use this one while we investigate what's causing the issues with the syntax you're currently using.
This issue only occurs with onUpdate hooks. See this fiddle showing that issue is not present in onMount
I’m starting to feel like a QA Engineer 👷♀️
thanks for all your work and responses to all my questions!
updated: https://github.com/BuilderIO/mitosis/issues/442
for svelte the issue is with inline arrow functions with and without {}
working () =>
https://mitosis.builder.io/?outputTab=svelte&code=import+%7B+useState%2C+onUpdate%2C+onMount+%7D+from+%22%40builder.io%2Fmitosis%22%3B%0A%0Aexport+default+function+MyComponent%28props%29+%7B%0A++const+state+%3D+useState%28%7B%0A++++name%3A+%22Steve%22%0A++%7D%29%3B%0A%0A++onMount%28%28%29+%3D%3E+%7B%0A++++state.name+%3D+%27hola%27%3B%0A++%7D%29%3B%0A%0A++return+%28%0A++++%3Cdiv%3E%0A++++++%3Cinput%0A++++++++css%3D%7B%7B%0A++++++++++color%3A+%22red%22%2C%0A++++++++%7D%7D%0A++++++++value%3D%7Bname%7D%0A++++++++onChange%3D%7B%28event%29+%3D%3E+state.name+%3D+event.target.value+%7D%0A++++++%2F%3E%0A++++++Hello%21+I+can+run+in+React%2C+Vue%2C+Solid%2C+or+Liquid%21%0A++++%3C%2Fdiv%3E%0A++%29%3B%0A%7D
broken with () => {}
https://mitosis.builder.io/?outputTab=svelte&code=import+%7B+useState%2C+onMount+%7D+from+%22%40builder.io%2Fmitosis%22%3B%0A%0Aexport+default+function+MyComponent%28props%29+%7B%0A++const+state+%3D+useState%28%7B%0A++++name%3A+%22Steve%22%0A++%7D%29%3B%0A%0A++onMount%28%28%29+%3D%3E+%7B%0A++++state.name+%3D+%27hola%27%0A++%7D%29%0A++%0A++return+%28%0A++++%3Cdiv%3E%0A++++++%3Cinput%0A++++++++css%3D%7B%7B%0A++++++++++color%3A+%22red%22%2C%0A++++++++%7D%7D%0A++++++++value%3D%7Bstate.name%7D%0A++++++++onChange%3D%7B%28event%29+%3D%3E+%7B+state.name+%3D+event.target.value+%7D%7D%0A++++++%2F%3E%0A++++++Hello%0A++++++%7Bstate.name%7D%21+I+can+run+in+React%2C+Vue%2C+Solid%2C+or+Liquid%21%0A++++%3C%2Fdiv%3E%0A++%29%3B%0A%7D
const useBindValue = (json: MitosisComponent, options: ToSvelteOptions) => {
traverse(json).forEach(function (item) {
if (isMitosisNode(item)) {
const { value, onChange } = item.bindings;
if (value && onChange) {
if (
onChange.code.replace(/\s+/g, '') ===
`${value.code}=event.target.value`
) {
delete item.bindings.value;
delete item.bindings.onChange;
item.bindings['bind:value'] = value;
}
}
}
});
};
https://github.com/BuilderIO/mitosis/blob/main/packages/core/src/generators/svelte.ts#L250...L266
onChange.code.replace(/\s+/g, '') === `${value.code}=event.target.value`
^ this code is outdated we now allow for custom event names and this only works if you don't use the arrow function brackets
I made a fix for svelte https://github.com/BuilderIO/mitosis/pull/439/commits/c17d05321abb82fc35cf687cf872c42441e832fd
@PatrickJS Not sure why you changed this github issue though. Does #439 fix useState + onUpdate for Angular? I don't see changes in the snapshot there indication so...
Did you mean to create a separate ticket for the svelte bug?
the angular output looks fine to me
https://stackblitz.com/edit/angular-mxdo5g?file=src%2Fapp%2Fapp.component.html
the angular output looks fine to me https://stackblitz.com/edit/angular-mxdo5g?file=src/app/app.component.ts
This link looks unrelated to me? @CKGrafico 's fiddle link in the original post is still broken. I tested it on your branch (pulled locally) and it still incorrectly uses setName
I'm reverting your changes to this issue. Feel free to create a separate issue for the Svelte problem if that feels like a different scope, or we can keep both here.
isn't that an issue with useState examples? Mitosis state is
const state = useState({})
or do we support both ways (react-way)
@PatrickJS Read this thread in full please.
I explained in https://github.com/BuilderIO/mitosis/issues/425#issuecomment-1143603976 that we support both formats, and that the [foo, setFoo] = useState() format is still supported across all frameworks, and there is a bug in combining that syntax with usage of setFoo within onUpdate
the helpers to convert all of those all live in the react generator so we would have to move all of those to helpers and apply them to every framework
updateStateSetters, updateStateSettersInCode, getUseStateCode https://github.com/BuilderIO/mitosis/blob/main/packages/core/src/generators/react.ts