Honor Late in Coming

Just before the Memorial Day weekend, the news broke that New Mexico State Senator John Pinto walked on at age 94. Pinto was one of very few surviving Navajo code talkers from WWII. In the hope of…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




Understanding React Hooks from the perspective of Render Versioning

React Hooks has been officially released in React v16.8.0 earlier this year and it’s getting more and more adoption across the world over the past few months. Basically, it is a new way to write functional components that are as powerful as, or even more powerful than, Class-based components. It not only enable us to write codes that are easier to organize and understand, but also allow us to gain potential performance improvements with the upcoming React Concurrent mode.

As an experienced React developer, I find it quite challenging to change my mindset from Class-based to Hooks-powered components in the beginning. It took me many hours and dozens of trials and experimentations just to grasp a basic understanding. Especially when I was heavily influenced by what the “old-school” Class-based components offer: life-cycle events, Class instance properties for storing data and imperative methods, etc.

Yes, like version control! 😆

In React, we know that a functional component is a simple function that takes some props and returns something for React to render. Functional component used to be “pure” (as formerly the best practice to do so). Namely, given the same props, it should always return the same result. However, it’s not pure anymore with Hooks. Hooks provides many tools for us to write “impure” functional components.

Props, state (useState and useReducer) and context (useContext) are the primary factors that account for render versioning. A change to one of these values, or to multiple of them at the same time, will trigger the component’s re-render. In addition to these primary factors, refs (useRef), callbacks (useCallback), imperative handles (useImperativeHandle) and side-effects (useLayoutEffect and useEffect) are also important factors you need to get the final render result, which in whole contributes to the render versioning. I’ll explain this later in this article.

To understand it, let’s begin with this Button component below. The initial render is Version 0 (count = 0). When we click the button, the component’s internal state count is changed, triggering the component to re-render, so we get Version 1 (count = 1). Click again, and we get Version 2 (count = 2).

Now, what if the Button component’s parent component Page is updated and re-rendered, causing Button to re-render? Good question! In this case, we are still left with Version 2 (count = 2). Because its internal state count hasn’t changed, and count is the only factor that accounts for the render versioning of Button component.

Nevertheless, this Button component is just a simplified example to illustrate the basic factors of Render Versioning. In real world scenarios, components are much more complicated, we should be careful to take all the versioning factors as mentioned above into consideration.

Any update (previous !== current) to one or more of the following factors will trigger re-render and change the component’s Render Version.

These versioning factors are somewhat different from the primary ones above. Because the hook functions to declare these values provide an extra dependencies param to bail out reference change. We can utilize it to ensure these factors remain the same reference (previous === current) upon re-render. However, be cautious for advanced usages, such as reading/updating state from callbacks. Make sure the callback function and the value it reads are on the same Render Version, avoid any stale access.

As we adopt the mindset of Render Versioning, many seemingly weird Hooks behaviors could be explained and understood in a simple and elegant way.

To further explore these topics, I’ll write another article in the near future.

Refactoring codes from Class-based to Hooks-powered require lots of effort. The Rendering Version mindset is based on my many experiments and failed attempts, and summarized from such experience of refactoring a fairly large code base. It helped me a lot. And I hope it would benefit you too.

If anything in this article is not clear, or do you have any questions, thoughts, suggestions or corrections to point out, please feel free to leave a comment below.

Add a comment

Related posts:

Problem Statement

EYE-HELPER is a project idea that originated from a survey by an NGO. It made us realize that there are a number of students who are visually impaired and they do not have access to appropriate…

Without Borders Newsletter 18

Anytime you put pen to paper you have the capacity to change someone else’s perspective and build your own. You have the power to bring healing at a time when it seems we can’t escape our own…

How to build an effective website

Building a website is an essential task for businesses and individuals looking to establish their online presence. A well-designed website can help you to attract potential customers, showcase your…