tcpiper
tcpiper

Reputation: 2554

Vue data binding doesn't work in functional component

When clicking the button, you will see n is getting bigger but the UI remains 1

<script>
let n = 1
function add() {
  console.log(n)
  return ++n
}
export default {
  functional: true,
  render(h, ctx) {
    return (<div>
      <h1>{n}</h1>
      <button onClick={add}>click</button>
    </div>)
  }
}
</script>

Upvotes: 1

Views: 99

Answers (1)

Dan
Dan

Reputation: 63129

Intended Behavior

This is the intended behavior of functional components and the thing that makes them functional. From the docs:

...we can mark components as functional, which means that they’re stateless (no reactive data)

Since functional components are just functions, they’re much cheaper to render.

Explanation

What this means-- and the reason n is not reactive-- is that n is not observable and has no dependency management/watching. This lack of dependency overhead is also the reason for the performance increase of functional components. You get speed at the cost of observability, which is a nice tradeoff if you don't need it. If you do, there would be no reason to use a functional component.

How to proceed

So, you could proceed to simply use a non-functional component, or, reason about whether it's possible to subdivide your functional component further and encapsulate only the reactive portions into a non-functional subcomponent.

Other thoughts

If you manually added observability to your functional component, you would get the behavior you wanted, though there's no reason to do this over using a non-functional component. Notice the use of observable:

import Vue from 'vue';
let state = Vue.observable({n: 1});

function add() {
  console.log(state.n)
  return ++state.n
}

export default {
  functional: true,
  render(h, ctx) {
    return (<div>
      <h1>{state.n}</h1>
      <button onClick={add}>click</button>
    </div>)
  }
}

(Note: You can use render functions in normal components as well. I say this just in case you had a misunderstanding that a functional component was required for render functions.)

Upvotes: 1

Related Questions