@_georgemoller
You don’t always need
useEffect()
Less code Less bugs Faster code
When you need to calculate something based on Instead, calculate it during rendering phase
props or state change, don’t put it inside useEffect.
@_georgemoller
What does Render mean in React?
Render is just a fancy word for saying that React is calling
one of your components.
<Modal <Modal
state of <Modal
changes
isOpen: false isOpen: true
(state) (state)
React calls/invokes your
component with the new state.
@_georgemoller
Using variants from
base components
Close for modification Click me!
Core behavior and UI is isolated in <ButtonBase
Open for extension
New variants can be created by extending <ButtonBase
@_georgemoller
Using variants from
base components
Close for modification
Click me!
Core behavior and UI is isolated in <ButtonBase
Open for extension
New variants can be created by extending <ButtonBase
1
useImperativeHandle()
Use useImperativeHandle to tell React to
expose your own custom object as the value of
a ref to the parent component.
@_georgemoller
2
useImperativeHandle()
inputRef.current points to the object returned by the
useImperativeHandle function.
This is why we have access to the focus function,
which uses the realInputRef.
@_georgemoller
@_georgemoller
R e act h o o ks .
useId
useId is a React Hook for generating
unique IDs that can be passed to
accessibility attributes.
useId should not be used to generate keys in
a list. Keys should be generated from your
data.
2
Useful custom hook:
useEffectAfterMount()
useEffect runs once after component
mounts and runs everytime the
dependencies change.
useEffectAfterMount will skip running
after component mounts, and it will only
run after dependencies change.
ERROR DON’T SPREAD
...DEPENDENCIES ON ARRAY
@_georgemoller
useEffect useLayoutEffect
State Changes State Changes
React re-renders React re-renders
component component
DOM is updated DOM is updated
browser repaints useLayoutEffect
the screen runs
browser repaints
useEffect runs
the screen
@_georgemoller
@_georgemoller
useEffect cheatsheet
useEffect(() => {
useEffect(() => {
useEffect(() => {
/*...*/
/*...*/
/*...*/
}) }, [state, props]) }, [])
Syncs with all data, Syncs with state & Syncs with no data,
runs after every props, runs after any runs only once after
render of these changes
first render
@_georgemoller
R e act h o o ks .
useDeferredValue
useDeferredValue is a React hook that delays the update
of a state value
Let’s suppose we have a SlowList
component that
Receives a search value
Performs an expensive
computation
Filters a country list by the
search term.
@_georgemoller
R e act h o o ks .
Info
If we type into the input again, React will abandon
the current render and restart with the new value.
This is how it “skips” expensive calculation unless
it’s the last deferred value.
search deferredSearch
s
“ “
se
s
sen
se
sene
sen
seneg
sene
senega
seneg
senegal
senega
senegal senegal
@_georgemoller
R e act h o o ks .
useDeferredValue
The Solution
useDeferredValue provides a deferred
version of the value that we pass in to it.
How it works
React first re-renders with the new
search (e.g. "Un") but the old
deferredSearch (still "U").
In the background, React tries to re-
render with both search and
deferredSearch updated to "Un".
@_georgemoller
R e act h o o ks .
useDeferredValue
The Problem
On every key stroke on the search input, the
UI feels slow, because we are performing the
expensive computation inside the SlowList
component everytime the search value
changes.
The user doesn’t see the input’s value
update immediately.
Manage who can view this folder
Thinking in
React components Choose which group has access to this folder:
All investors Only selected
Selected investors who have access to this folder:
<Modal <RadioButton
Search for investors
<Modal.Header <SearchField
Name Has access?
<List
<Modal.Body
Michael Scott
<ListHeader
<Modal.Footer Pam Beasley
<Button <ListItem Jim Halpert
Cancel Save changes
@_georgemoller
@_georgemoller
Modal Component
React: re-renders phases
modal
isOpen = false when state updates
Trigger Phase Render Phase Commit Phase
User clicks on open modal (React calls modal component with (React modifies the dom)
button isOpen = true)
modal DOM
Open modal
modal
isOpen = true
setIsOpen(true)
Redux data flow
event handler reducer
Open Sidebar
switch (action.type) {
dispatch(setIsSidebarOpen(true))
case SET_IS_SIDEBAR_OPEN:
return {
User interaction: clicks on
...prevState,
a button to open the isSidebarOpen: action.payload
sidebar }
action creator
function setIsSidebarOpen (isOpen) {
Updates store
return {
type: SET_IS_SIDEBAR_OPEN,
payload: isOpen
store
}
(global state)
/***/
isSidebarOpen: true,
/***/
@_georgemoller
React state tips!
Group related state
If two or more state variables are likely to
change together, then you should consider
putting those variables into an object.
@_georgemoller
@_georgemoller
React state tips!
Avoid redundant state
Calculations from props or state should not be put in
the component’s state.
React state tips!
Resetting a component’s
state with a key
Whenever you pass in a different key to a
component you are resetting the
component’s state.
This function will change the <Form
component key, resetting its state.
@_georgemoller
@_georgemoller
React ref tips!
Don’t write/read a ref.current
during rendering.
Calculations from props or state should not be put in
the component’s state. You can read or write refs from event
handlers or effects instead.
@_georgemoller
React project structure
(opinionated)
src
assets assets folder contains all static files such as images, fonts etc.
utils everything that is shared between components or features, e.g. functions, hooks, etc.
features components that represent a feature should live here, alongside their tests, styles, etc.
components truly generic, reusable components, usually atoms and molecules like buttons, dropdown.
api API request declarations.
routes routes configuration for each route in the app.
locales holds internationalization config, entries and messages for each language.
router.js entry point for routes, this file is a small wrapper around routes to delegate routes usage.
app.js entry point of the app.
@_georgemoller
React project structure
(opinionated)
src
assets utils features components api
images hooks PostsList Button Auth.js
vendor functions PostsList.jsx
Post.js
PostsList.styles.js
tests
httpClient.js
index.js
__tests__
@_georgemoller
React project structure
(opinionated)
src
routes locales router.js app.js
Auth.js entries
Post.js
en-US.js
es-ES.js
messages
en-US.js
es-ES.js
index.js
georgemoller2106 @_georgemoller
React
React hooks cheatsheet
State
useState()
Declares a state variable.
useReducer()
Declares a state variable managed
with a reducer.
Context
useContext()
Reads and subscribes to a context.
georgemoller2106 @_georgemoller
React
React hooks cheatsheet
Events
useEvents()
Extract non-reactive effect logic into an
event function.
Transitions
useDeferredValue()
Defer to more urgent updates.
useTransition()
Lets you mark updates in the provided
callback as transitions.
georgemoller2106 @_georgemoller
React
React hooks cheatsheet
Accessibility
useId()
Generate unique IDs across the server and
client.
Debugging
useDebugValue()
Display a label for custom hooks.
georgemoller2106 @_georgemoller
React
React hooks cheatsheet
Refs
useRef()
Declares a ref.
useImperativeHandle()
Customize instance value exposed to
parent refs.
georgemoller2106 @_georgemoller
React
React hooks cheatsheet
Memoization
useCallback()
Return a memoized callback.
useMemo()
Return a memoized value.
georgemoller2106 @_georgemoller
React
React hooks cheatsheet
Effects
useInsertionEffect()
Insert styles into the DOM.
Subscribing
useSyncExternalStore()
Subscribe to external state.
georgemoller2106 @_georgemoller
React
React hooks cheatsheet
Effects
useEffect()
Synchronize external state.
useLayoutEffect()
Read layout DOM state.
Displaying React @_georgemoller
Components Flow
Trigger a Render
Initial Render State Updates
React queues a render
const root = createRoot(...)
setSomeState(...)
root.render(...)
Render
React Renders Your
component/s React calls your component/s
Commit
React commits
changes to the DOM React updates the DOM
Browser
Rendering Browser paints the changes on the screen
@_georgemoller
React Component structure
src
components
Button
Button.tsx react component
index.tsx util file to export everything from Button.tsx
Button.stories.tsx stories from storybook live here
Button.styles.tsx styles from styled-components library
tests
Button.test.tsx where most of unit tests live
How to properly @_georgemoller
useCallback()
Bad use case Good use case
@_georgemoller
React
Prevent impossible states
isTyping = true isEmpty = false
isTyping = false isEmpty = true
isTyping = false isEmpty = false
isTyping = true isEmpty = true
4 possible combinations
1 imposible state
@_georgemoller
React
Prevent impossible states
You can remove impossible states, by
combining these into a status variable
that holds only one of these values:
‘empty’ or ‘typing’.
How useMemo() works
in React?
useMemo will only recompute a value
when one of the dependencies has
changed.
This will be recalculated only when
users or occupation props change.
@_georgemoller
@_georgemoller
Introduction to useMemo()
useMemo is a React hook used to skip expensive calculations by
remembering the result of these between re-renders.
Every time React re-renders this component,
filterTodos() function will re-run.
@_georgemoller
useMemo() to the rescue
If filterTodos() is an expensive function, we can optimize it by caching
(remembering) the return value between re-renders.
You can measure the time of a calculation
by using console.time()
Greater than 1ms is consider expensive.
@_georgemoller
When to useMemo()?
You have an expensive function on a
1 component that often re-renders (due to
props or state change)
2 You pass it as a prop to a component
wrapped in memo.
The function is later used as a dependency of
3 some Hook (e.g. another useMemo or
useEffect).
@_georgemoller
useMemo() dependencies
Be careful of the dependencies you pass into the useMemo hook. If
these always change between re-renders, it defeats the purpose of
using useMemo().
@_georgemoller
How to use encapsulation in your
React components.
User component knows too much about the
user.
e.g. address has other properties that are not
being consumed by <User so no need to
expose them.
@_georgemoller
How to use encapsulation in your
React components.
UserModel encapsulation can prevent unwanted access
to sensitive data (preferences). You can go one step
further and also hide information through access
modifiers and reduce unwanted changes on properties.
@_georgemoller
How to create extensible
React components.
Dropdown isn’t closed for modification
as we need to change it in order to
extend it, in other words: it isn’t open for
extension.
@_georgemoller
How to create extensible
React components.
Now dropdown doesn’t care about
how options are rendered.
It’s up to the component’s consumer
to determine how to show the
options.
@_georgemoller
How to create extensible
React components.
Dropdown can expose some style conditions
on how options should be displayed, but is up
to the consumer to determine its content.
@_georgemoller
How to create extensible
React components.
Now Dropdown is closed for modification
as we don’t need to change it in order to
extend it, in other words: it is open for
extension.
@_georgemoller
Build a dropdown UI using
React Components
United States
Australia
Austria
Azerbaijan
@_georgemoller
<Dropdown
<Toggle
United States
Build a dropdown
Australia
UI using React <Item
Austria
Components Azerbaijan
<Menu
@_georgemoller
Build a dropdown
UI using React
Components
@_georgemoller
1
Identify logic that Logic that can be reused
can be reused
@_georgemoller
2
Extract that logic into
a custom hook
@_georgemoller
3
Call the custom hook from components
that use that logic.
Difference between useMemo() and @_georgemoller
useCallback() in React?
useCallback() useMemo()
useCallback will remember a function between renders. useMemo will remember a value between renders.
Used to fix performance issues, e.g. when changing a Used to avoid re-calculating expensive operations.
function can cause expensive components to re-render.
@_georgemoller
Common React mistake
When using conditional rendering, and using &&, don’t put
numbers on the left side of &&.
If the left side is 0, then the whole
expression gets that value (0).
Instead do:
users.length > 0.
Avoid this useEffect()
mistake
1 The Toggle updates its state first, and
React updates the screen.
2 Then React runs the Effect, which calls
the onChange function passed from a
parent component.
3 Now the parent component will update
its own state, starting another render
pass.
@_georgemoller
Instead notify of the state
change directly on the event
handler.
1 The Toggle updates its state first and
notifies the parent component at the
same time, in the event handler.
@_georgemoller