Reputation: 2554
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
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