Posted onWord count in article: 14kReading time ≈13 mins.
Notes for React Hooks.
General
Hooks can only be called at the top level of a function component or
a custom hook. You can't call it inside loops or conditions.
In Strict Mode, React will call your calculation function twice in
order to help you find accidental impurities. This is development-only
behavior and does not affect production.
useState hook
Syntax
1
const [state, setState] = useState(initialState)
Calling the set function does not update the state
variable in the already running code. To solve this problem, you may
pass an updater function to setState.
React will ignore your update if the next state is equal to the
previous state, as determined by an Object.is comparison.
This usually happens when you change an object or an array in state
directly.
In function components, the initial state computation is declared in
the render function and happens every render. Having a slow initial
state computation can slow down an entire application significantly.
By passing a function version of the initial state, you will no
longer run the slow computation each render, but only once on the first
render of the component just like class components.
When the ChatRoom component above gets added to the
page, it will connect to the chat room with the initial
serverUrl and roomId. If either
serverUrl or roomId change as a result of a
re-render, your effect will disconnect from the previous room, and
connect to the next one.
Try to write every effect as an independent process and think about a
single setup/cleanup cycle at a time.
An effect lets you keep your component synchronized with some
external system. Here, external system means any piece of code that's
not controlled by React. Such as: * A timer managed with
setInterval() and clearInterval() * An event
subscription using addEventListener() and
removeEventListener() * A third-party animation library
with an API like animation.start() and
animation.stop()
Controlling a non-React
widget
For example, if you have a third-part map widget or a video player
component written without React, you can use an Effect to call methods
on it that make its state match the current state of your React
component.
You can use an effect to fetch data for your component. Note that if
you use a framework, using your framework's data fetching mechanism will
be a lot more efficient that writing effects manually.
Updating
state based on previous state from an effect
When you change the ref.current property, React does not
re-render your component. Do not write or read ref.current
during rendering, except for initialization.
Usage
Refenrencing DOM elements
The most common use case for refs in React is to reference a DOM
element.
The syntax of useLayoutEffect is identical to
useEffect, but it fires synchronously after all DOM
mutations. Use this to read layout from the DOM and synchronously
re-render. Updates scheduled inside useLayoutEffect will be
flushed synchronously, before the browser has a chance to paint.
Prefer the standard useEffect when possible to avoid
blocking visual updates.
Usage
Measuring
layout before the browser repaints the screen
forwardRef is a higher order component that takes a
component as its first argument and returns a new component that
forwards the ref to the component it wraps.
ref: An ref you received as the second
argument from the forwardRef call.
createHandle: A function that takes no arguments and
returns the ref handle you want to expose. That ref handle can have any
type. Usually, you will return an object with the methods you want to
expose.
dependencies: The list of all reactive values
referenced inside of the createHandle function.
The subscribe function should subscribe to the store and
return a function that unsubscribes. The getSnapshot
function should return the current state of the store. The store
snapshot returned by getSnapshot must be immutable.
The store snapshot returned by getSnapshot must be
immutable. If the underlying store has mutable data, return a new
immutable snapshot if the data has changed. Otherwise, return a cached
last snapshot.
If a different subscribe function is passed during a
re-render, React will re-subscribe to the store using the newly passed
subscribe function. You can prevent this by declaring
subscribe outside the component.
If the store is mutated during a non-blocking transition update,
React will fall back to performing that update as blocking.
Specifically, for every transition update, React will call
getSnapshot a second time just before applying changes to
the DOM. If it returns a different value than when it was called
originally, React will restart the update from scratch, this time
applying it as a blocking update, to ensure that every component on
screen is reflecting the same version of the store.
Usage
Subscribing to an external
store
1 2 3 4 5
import { todosStore } from'./todoStore.js'
functionTodos() { const todos = useSyncExternalStore(todosStore.subscribe, todosStore.getSnapshot); }
The subscribe function should subscribe to the store
and return a function that unsubscribes.
The getSnapshot function should read a snapshot of the
data from the store.
React will use these functions to keep your component subscribed to
the store and re-render it on changes.
Comes with React 18. useDeferredValue is a hook that
lets you defer updating a part of the UI.
Syntax
1
const deferredValue = useDeferredValue(value)
During the initial render, the returned deferred value will be the
same as the value you provided. During updates, React will first attempt
a re-render with the old value, and then try another re-render in
background with the new value.
ComeswithReact18.`useTransition` is a hook that lets you update the state without blocking the UI. This works like `useMemo`, but the value is computed asynchronously.