BuilderIO / mitosis

Write components once, run everywhere. Compiles to React, Vue, Qwik, Solid, Angular, Svelte, and more.
https://mitosis.builder.io
MIT License
12.58k stars 561 forks source link

useStore naming the returned variable other than state will not work #788

Open cadamsdev opened 2 years ago

cadamsdev commented 2 years ago

Problem

If you name the returned variable from useStore anything other than state then the hook will not output properly in React or Angular.

e.g (Will not work!)

  const store = useStore({
    name: 'Steve'
  });

However this works

  const state = useStore({
    name: 'Steve'
  });

I am interested in helping provide a fix!

Yes

Which generators are impacted?

Reproduction case

https://mitosis.builder.io/?outputTab=E4UwhgxgLkA%3D&code=JYWwDg9gTgLgBAbzgVwM4FMDKNrrgXzgDMoIQ4AiAAQCNlgAbAE3SgDpgIB6EYHVYKgoBuAFCj0AD0iw4LIgENkDeEWQA7AMYxO6uAFkAngGEykdenUwAFGFJhUASkSi4cTRHWp433HAC8KBjYuNYIrm5w6gog6ABccADk2OgAbuiJEfiOYhFQ6DDIUHrWEW4APEzAqQB8ZZEIvvls0bH49eVcVbUROaL4QA

Expected Behaviour

React (Should not have store.name in template)

import * as React from "react";
import { useState } from "react";

export default function MyComponent(props: any) {
  const [name, setName] = useState(() => "Steve");

  return <div>{name}</div>;
}

Angular (Same issue should not have store.name in template)

import { Component } from "@angular/core";

@Component({
  selector: "my-component, MyComponent",
  template: `
    <div>{{name}}</div>
  `,
})
export default class MyComponent {
  name = "Steve";
}

Actual Behaviour

React

import * as React from "react";
import { useState } from "react";

export default function MyComponent(props: any) {
  const [name, setName] = useState(() => "Steve");

  return <div>{store.name}</div>;
}

Angular

import { Component } from "@angular/core";

@Component({
  selector: "my-component, MyComponent",
  template: `
    <div>{{store.name}}</div>
  `,
})
export default class MyComponent {
  name = "Steve";
}

Additional Information

Tested with mitosis version: 0.0.69

To workaround this problem, you either have to make sure you name the returned variable "state"

  const state = useStore({
    name: 'Steve'
  });

or use destructuring.

  const { name } = useStore({
    name: 'Steve'
  });

https://mitosis.builder.io/?outputTab=E4UwhgxgLkA%3D&code=JYWwDg9gTgLgBAbzgVwM4FMDKNrrgXzgDMoIQ4AiAAQCNlgAbAE3SgDpgIB6EYHVYKgoBuAFCj0AD0iw4LIgENkDeEWQA7AMYxO6uAFkAngGEykdenUwAFAEpEouHE0R1qeEnUKQeQgF4UDGxcawRHJzgvHwAuOABybHQAN3Q48PxbMXCodBhkKD1rcKcAHiZgJIA%2BYoiEKPR8GpKucqrwzNF8IA

Though the docs don't show using destructuring so both syntaxes should be supported. https://github.com/BuilderIO/mitosis/blob/main/docs/hooks.md

samijaber commented 2 years ago

This is a known limitation. It is not documented explicitly in docs, but programmatically enforced via our ESLint plugin: https://github.com/BuilderIO/mitosis/blob/55e3ecc8d3224bf780889f607ed2b59389269f7b/packages/eslint-plugin/docs/rules/use-state-var-declarator.md

We highly recommend that you setup the ESLint plugin on your machine/codebase using the recommended config so that you are warned against this (& many other rules) on how to write valid Mitosis component code