Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about the functional API with function components #61

Closed
bskimball opened this issue Jun 24, 2019 · 7 comments
Closed

Question about the functional API with function components #61

bskimball opened this issue Jun 24, 2019 · 7 comments

Comments

@bskimball
Copy link

bskimball commented Jun 24, 2019

I'm curious to what functional components would look like in Vue 3. Obviously the talk of the town is adding setup() and the examples show using createElement and templates. I like jsx and currently use it in Vue and I also like React + hooks, but for the same reasons @yyx990803 and @Akryum have noted, it could be improved. I have already tried out the vue-function-api plugin which only seems to work with templates at this time.

I assume in Vue 3 a typical component with jsx would look like this

import { value, onMounted } from "vue";

const TestCounter = {
  setup() {
    const count = value({ value: 0 });

    onMounted(() => {
      console.log("mounted");
    });

    return () => (
      <div>
        {count.value}
        <div>
          <button onClick={() => (count.value = count.value + 1)}>
            increment
          </button>
        </div>
      </div>
    );
  }
};

export default TestCounter;

I also have used the vue-hooks package and I really like that api, for it's simplicity, and as you can see in the example above the object only has 1 function. This makes me think an actual functional component would just return the setup.

import { value, onMounted } from "vue";

function TestCounter() {
  const count = value(0)
  
  onMounted(() => {
    console.log("mounted")
  })
  
  return (
    <div>
      {count}
      <div>
        <button onClick={() => (count = count + 1)}>
          increment
        </button>
      </div>
    </div>
  )
}

What I have in this example would be the preferred api for me. I was wondering if this is what the Vue team had envisioned. Thank you.

@leopiccionia
Copy link

The second example misses improvements of function-based component API over both React Hooks and vue-hooks, most notably:

Not called repeatedly on each render and produce less GC pressure

Moreover, setup signature ((initialProps, context)) is different from render signature ((props, slots, attrs, vnode)). How to reconcile them?

@LinusBorg
Copy link
Member

"functional components" as described in RFC #27 are pure functions that receive props & context and return virtualDOM.

They don't create any instance that we could bind data to and don't have any lifecycle of their own, so the API proposed in #42 will not be usable in functional components.

@bskimball
Copy link
Author

bskimball commented Jun 24, 2019

Thanks for the replies. What I don't understand is how you would take advantage of the improvements of the api if you are just returning createElement or jsx from the setup function. Mentally it would probably make more sense to me if jsx was still returned from the render function.

import { value, onMounted } from "vue";

const TestCounter = {
  setup() {
    const count = value({ value: 0 });

    onMounted(() => {
      console.log("mounted");
    });
  },

  render() {
    return (
      <div>
        {count.value}
        <div>
          <button onClick={() => (count.value = count.value + 1)}>
            increment
          </button>
        </div>
      </div>
    )
  }
};

export default TestCounter;

Maybe I'm reading the RFC wrong in regards to manually rendering.

@posva
Copy link
Member

posva commented Jun 24, 2019

So the thing is in a functional component there is no state, no hooks and no computed, there are only props, that's why it's not concerned by the function api

@bskimball
Copy link
Author

Yes. Thank you. I understand that now. I was just wondering what using jsx would look like with the composition functions api.

I'm excited about the additions.

@beeplin
Copy link

beeplin commented Jun 24, 2019

originally in rfc #42 there were both setup and render functions, just like what you said. Then people figured out that letting setup returning JSX is a better design for type inference.

@yyx990803
Copy link
Member

@bskimball putting the setup code along side the JSX expression means all the code needs to be run on every single render. This creates all kinds of issues mentioned here, which is exactly what we are trying to avoid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants