Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Functional components are re-rendered when props are unchanged. #4037
Steps to reproduce
Open the jsfiddle, click the button multiple times.
What is Expected?
Both component not to be re-rendered if the props are not changing.
What is actually happening?
The functional component is re-rendered when the props are unchanged.
To optimise and avoid expensive renders in a complex application, I'm moving most of the HTML logic to functional components and expect them not to be re-rendered if the data passed doesn't change.
If this is intended, perhaps the docs should reflect this quirk, but I don't see any reason why we should always call the render function when we can safely assume the resulting HTML to be unchanged (same input == same output).
I wonder whether it is a bug or an intended feature. According to the doc, functional components are cheap to render. IMHO, the rendering expense of computing reactivity is not required in functional components. It is misleading to think functional components are magically cheaper. They just do less than ordinary components.
If functional components are reactive to their props, its cheap nature is not preserved. Users should just keep their function stateless and functional. Yes, a pure function.
In the code above,
@HerringtonDarkholme I respectfully disagree: The use of Date in my example is intended, as that's a good way to check whether the render function has been called when the inputs are unchanged. How do you force a pure function to change its output while keeping the inputs unchanged? Call an impure function.
The point is not the use of Date, is that this.render is called on a functional component even when not necessary. This is a bug IMO, because even if functional components are cheap to render (!= free to render), it does not mean we have to render it in all cases, as their very purpose and reason to exist is to give us a simple way of determining whether we can safely skip rendering them. So safely skip rendering them we should when the conditions are appropriate.
FYI, functional components in Vue are "eager", which means the render function gets called directly during the parent's render cycle without allocating any instance for the child. Because there is no instance associated with them, there's no easy way to perform memoization of previous render results. The desired optimization is not easily obtainable while ensuring correctness in all possible cases.
That said, the lack of instance in functional components is a pretty big perf win in most cases, especially for leaf components that are used in large numbers. But it may not be the best choice for complex one-off components, where the presence of an instance allows it to take advantage of static optimization and reactivity boundary.
React's functional components are also always re-rendered: facebook/react#5677
I'd be open to suggestions on how this can be achieved, but for now I don't see an actionable path forward.
I know this issue has been closed for a while, but I just have a small follow-up question, that wouldn't justify its own issue:
Like stated a functional component always rerenders, not just when no props have changed, but even when it doesn't have any props at all. This behaviour changes, when the
Would it be recommended to make such a component non-functional?