According to the React 16.x Roadmap, we can expect Concurrent Mode soon.
React 16.x (~Q2 2019): The One with Concurrent Mode
Concurrent Mode allows React apps to be more responsive by rendering component trees without blocking the main thread.
It is opt-in and allows React to interrupt a long-running render (for example, rendering a new feed story) to handle a high-priority event (for example, text input or hover).
Concurrent Mode also improves the user experience of Suspense by skipping unnecessary loading states on fast connections.
While it is an opt-in feature, you can enable it easily and if your component isn’t properly implemented, it won’t work correctly.
In short, you can’t make side effects in your render function. This has always been true, but it hasn’t been a real issue until we got Concurrent Mode.
In Concurrent Mode, render functions could be invoked multiple times without actually committing (meaning, for example, applying changes to the DOM).
Luckily, Strict Mode intentionally invokes render functions twice, and you can see the wrong behavior in development mode. Refer the doc for more information.
This short article focuses on
useRef, one of React’s Hooks. The
useRef Hook is pretty powerful and can often be misused. In general, developers should avoid using
useRef if they could use
This article shows example code that uses
useRef incorrectly and how to fix it.
The example is a simple counter just to illustrate the issue. It’s not product code, and you can actually implement the same example with
It works as expected in traditional React, where the render phase and the commit phase is one-to-one.
However, if it invokes the render function multiple times without committing, the count increases unexpectedly.
This code uses
useEffect, whose first argument function is only invoked in the commit phase.
currentCount is a local variable within the render function scope, and it will only change the ref
count in the commit phase. The ref is essentially a global variable outside the function scope, hence modifying it is a side effect.
To run the two code examples above, here’s the app component.
We don’t, in fact, need
StrictMode is enough.
Please check out the following “codesandbox” to see the actual behavior.
The reason I want to use
useRef is to develop a bindings library for Redux. It requires the subscription to the global store, and to update components when the state is updated.
The ref is used to keep track of the last rendered state. For more information, check out the GitHub repository.