Advanced React Handbook
Advanced React Handbook
This handbook covers intermediate to advanced React concepts, integrating related technologies and
best practices. It includes detailed explanations, code examples, diagrams, and tables to reinforce
learning. Citations refer to authoritative sources to ensure accuracy and up-to-date information.
The useEffect hook runs after render, letting you perform side effects (data fetching, subscriptions,
etc.). It optionally takes a dependency array to control when it re-runs:
function DataFetcher({ id }) {
const [data, setData] = useState(null);
useEffect(() => {
// Side effect: fetch data when component mounts or id changes
fetch(`/api/data/${id}`)
.then(res => [Link]())
.then(json => setData(json))
.catch(err => [Link](err));
• Dependency array: Passing [id] means the effect runs on mount and whenever id
changes. An empty array [] runs only once after the first render. Omitting it runs the effect
after every render (often undesirable).
• Cleanup: If your effect returns a function, React calls it before unmounting or before re-running
the effect. This is useful to cancel subscriptions or timers.
Common pitfalls include missing dependencies (causing stale values) or including too many (causing
infinite loops). Always list all state/props used in the effect dependencies to ensure correctness 1 2 .
1
useMemo and useCallback
React provides useMemo and useCallback to memoize values and functions between renders. This
avoids re-computing expensive calculations or re-creating functions on each render.
• useMemo(() => value, [deps]) : Caches a computed value until dependencies change.
• useCallback(fn, [deps]) : Caches the function fn (same reference) until dependencies
change.
Without useMemo , sortedItems would be recomputed on every render, even if items is the same.
useCallback is similar but for functions:
function Counter() {
const [count, setCount] = useState(0);
Optimization note: useMemo and useCallback introduce their own overhead. Use
them when there is a performance issue (e.g. expensive computation or large component
trees) 3 4 . Overusing memoization can complicate code without benefit.
Custom Hooks
Custom hooks encapsulate reusable logic. They are functions named with use prefix that call built-in
hooks. For example, a hook for window size:
2
import { useState, useEffect } from 'react';
function useWindowWidth() {
const [width, setWidth] = useState([Link]);
useEffect(() => {
const handleResize = () => setWidth([Link]);
[Link]('resize', handleResize);
return () => [Link]('resize', handleResize);
}, []);
return width;
}
function MyComponent() {
const width = useWindowWidth();
return <div>Window width: {width}</div>;
}
Custom hooks allow composition of logic across components and improve code organization. They
follow the Rules of Hooks (call hooks only at top level and from React components or other hooks) 5 .
The useRef hook creates a mutable ref object with a .current property. It can hold any value and
persists across renders without causing updates.
function TextInputWithFocus() {
const inputRef = useRef(null);
return (
<div>
<input ref={inputRef} />
<button onClick={() => [Link]()}>
Focus the input
</button>
</div>
);
}
• Instance-like refs: Use refs to hold mutable values (timers, previous props) that don’t trigger re-
renders. For example, to store a previous value:
function usePrevious(value) {
const ref = useRef();
useEffect(() => { [Link] = value; });
3
return [Link];
}
[Link] allows a component to accept a ref prop and forward it to a child. This is
useful when a parent needs to call imperative methods on a child’s DOM or expose internal functions.
For example:
function Parent() {
const fancyRef = useRef();
return (
<div>
<FancyInput ref={fancyRef} />
<button onClick={() => [Link]()}>
Focus FancyInput
</button>
</div>
);
}
React’s documentation notes that [Link] “returns a component that can accept a ref
prop and forward it to one of its children” 6 , enabling this pattern.
Additional Hooks
• useLayoutEffect : Similar to useEffect but fires synchronously after all DOM mutations.
Use it to measure layout before the browser paints.
• useImperativeHandle : As shown above, customizes the instance value exposed by a ref.
• State Hooks ( useState , useReducer ): While useState is basic, useReducer can
manage complex state logic (akin to Redux reducers) for predictable updates.
Best practices: Always place hooks at the top level of your component. Do not call hooks inside loops or
conditions, to maintain consistent order across renders 7 .
4
Context API and State Sharing
React’s Context API provides a way to share values (like theme, user, settings) across the component
tree without prop drilling. Create a context and wrap components in a Provider:
function App() {
return (
<[Link] value="dark">
<Toolbar />
</[Link]>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
return <div className={theme}>Toolbar</div>;
}
By default, any change to the value prop of a Provider triggers all consuming components to re-
render, even if they do not use the changed part. For example:
function App() {
const [count, setCount] = useState(0);
const theme = { color: 'blue' }; // new object each render
return (
<[Link] value={theme}>
<button onClick={() => setCount(c => c+1)}>Increment {count}</button>
<ChildComponent />
</[Link]>
);
}
Here, theme is a new object on each render, so all Context consumers re-render on any state change.
To optimize:
• Memoize context value: Wrap complex values in useMemo so the provider only changes when
needed 8 :
• Split contexts: Use multiple contexts if different parts of state can change independently, so
unrelated components only subscribe to what they need 9 .
5
• [Link] : For consumer components, wrap them with [Link] so they skip renders
when context value identity hasn’t changed (useful if context value rarely changes).
For example: As one source explains, “If you pass an object or array as value to a Context
Provider, a new reference is created on each render. Even if the actual data didn’t change,
consumers will re-render because the reference changed. Using useMemo to memoize the
context value prevents this unnecessary re-rendering.” 8 .
function App() {
const [darkMode, setDarkMode] = useState(false);
// Memoize to avoid passing a new object each time
const theme = useMemo(() => ({ color: darkMode ? 'dark' : 'light' }),
[darkMode]);
return (
<[Link] value={theme}>
<button onClick={() => setDarkMode(d => !d)}>
Toggle Dark Mode
</button>
<ThemedBox />
</[Link]>
);
}
By combining useMemo and [Link] , this example avoids redundant renders of ThemedBox
when unrelated state changes. Proper use of context and memoization is key to performance when
sharing state globally.
Error Boundaries
React error boundaries catch exceptions in child components and display a fallback UI instead of
crashing the whole app 10 . Only class components can be error boundaries (as of React 18).
6
// Update state to trigger fallback render
return { hasError: true };
}
componentDidCatch(error, info) {
// Log error (optional)
[Link]('ErrorBoundary caught:', error, info);
}
render() {
if ([Link]) {
return <h2>Something went wrong.</h2>;
}
return [Link];
}
}
<ErrorBoundary>
<Widget /> {/* Errors in Widget will be caught */}
</ErrorBoundary>
Key points: - Error boundaries catch errors during rendering, in lifecycle methods, and constructors
of children 10 .
- They do not catch errors inside event handlers, asynchronous code (e.g. setTimeout), or in themselves
11 .
- If an error is not caught by any boundary, React unmounts the entire component tree (worse than
showing broken UI) 12 . - Typically, wrap high-level routes or major UI sections with an error boundary
to isolate crashes.
Error boundaries are akin to a try/catch for React components, preserving app stability.
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
7
</Suspense>
);
}
Benefits: Faster initial load because code for off-screen parts is not loaded upfront.
Notes: - Only default exports can be lazy-loaded. - Always wrap lazy components in <Suspense> with
a fallback UI 13 . - You can nest <Suspense> boundaries to coordinate multiple lazy loads.
For route-based splitting, combine React Router with [Link] , loading each route’s component
only when needed. This significantly reduces the initial bundle size.
Portals
A portal allows rendering a React subtree into a DOM node outside the parent component’s DOM
hierarchy 14 . This is useful for elements like modals, tooltips, or dropdowns that should break out of
overflow or stacking contexts.
// Usage in App
<div>
<h1>Main App</h1>
<Modal>
<p>This is rendered into #modal-root in the DOM.</p>
</Modal>
</div>
Under the hood, createPortal(children, domNode) returns a React element that is inserted into
the specified domNode 15 . From React’s perspective, the portal content is still part of the parent
component’s tree (so context and event bubbling work normally) 16 17 .
For example, rendering a modal via a portal ensures it visually appears above all other content, even if
the parent’s CSS has overflow: hidden . Events propagate through the React tree, not the DOM
tree, so parent event handlers still work 16 18 .
8
Suspense and Concurrent Features (React 18+)
React 18 introduced new concurrency primitives and expanded Suspense beyond code-splitting:
• Suspense for Data Fetching (experimental): In future React versions or with specific libraries,
you can have components suspend rendering until data is ready. (This leverages <Suspense>
to show fallback content while waiting for data.) For now, libraries like Relay or React Server
Components use this pattern.
• useTransition Hook: Marks certain state updates as non-urgent (concurrent).
useTransition returns [isPending, startTransition] . Wrap a state update in
startTransition(() => { setState(...) }) to hint that this update can be interrupted
to keep the UI responsive 19 20 . While transitioning, isPending is true , letting you show a
pending indicator.
function Search() {
const [isPending, startTransition] = useTransition();
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
return (
<div>
<input value={query} onChange={handleChange} />
{isPending ? <p>Searching...</p> : <ResultList items={results} />}
</div>
);
}
Updates inside startTransition are interruptible—if a user types quickly, React may pause the fetch
update to process the latest keystrokes first. The isPending flag can show loading status.
useTransition is ideal for smoothing out input-heavy UIs 19 20 .
9
// Use deferredQuery to fetch or filter results
}
Here, if query changes often, deferredQuery lags behind slightly. React will first render with the
old value ( deferredQuery ), then start a background re-render with the new value once it’s available
21 . If the deferred render suspends (e.g. awaiting data), the user still sees the old results until the new
data is ready 22 .
• React Concurrent Mode: Enabled by default in React 18 when using createRoot . It includes
automatic batching and the above hooks. Concurrent Mode can make rendering non-blocking,
improving perceived performance for high-latency operations 23 24 .
Diagram: A typical visualization of React’s virtual DOM is shown below, illustrating how React keeps an
in-memory tree to efficiently update the real DOM:
Illustration of React’s “virtual DOM” concept: React maintains a lightweight copy of the UI (virtual DOM) to
batch and minimize updates to the real DOM 25 .
Profiling
Use the React DevTools Profiler to identify slow components. The Profiler tab records render timings
and highlights costly renders. Programmatically, React offers a <Profiler> component that wraps a
tree and calls an onRender callback on every commit 26 :
function onRenderCallback(
id, // Profiler id
phase, // "mount" or "update"
actualDuration, // time spent rendering
10
baseDuration // estimated time if no memoization
) {
[Link](`${id} rendered in ${actualDuration}ms (base ${baseDuration}
ms)`);
}
This can log how long rendering took, useful in custom performance tests. The callback provides
actualDuration (time including optimizations like memo) and baseDuration (time if no optimizations),
enabling you to gauge how well your memoization works 2 .
• Production Build: Always test performance in a production build ( npm run build ). Dev builds
include extra checks and are slower 27 .
• [Link] / PureComponent : Wrap functional components with [Link] to skip re-
renders when props are shallowly equal. Class components can extend
[Link] for similar effect 28 29 . This prevents unnecessary reconciliation of
subtrees.
• Keys in Lists: Always give list items stable, unique keys (not array index) to help React match
elements between renders. Correct keys enable React’s diff algorithm to minimize updates, while
wrong keys can cause full re-renders or bugs 30 .
• Avoid Anonymous Functions and Objects in Props: In parent components, avoid re-creating
functions or objects inline on every render (e.g.
<Child onClick={() => doSomething()} /> ). Use useCallback or useMemo to
stabilize these props; otherwise, child components will see new prop references each time and
re-render.
• Avoid Frequent State Updates: Batch state updates and avoid setting state in tight loops. Use
functional updates ( setState(prev => new) ) to enqueue updates efficiently.
• Virtualization: For large lists, use windowing libraries (e.g. react-window) so only visible items
are rendered. This saves rendering time and DOM nodes.
• Dependency Arrays: Define hook dependencies precisely to avoid redundant effect calls. As one
performance guide states, “Always define dependency arrays properly in hooks like useEffect or
useCallback . Incorrect dependencies can lead to effects running too often or not updating when
they should” 4 .
• Memoize Context Values: As discussed, wrap context provider values with useMemo to avoid
unwanted renders 8 .
function App() {
11
const [count, setCount] = useState(0);
const data = 'static data';
return (
<div>
<button onClick={() => setCount(c => c + 1)}>Increment</button>
<ExpensiveComponent data={data} />
</div>
);
}
Here, ExpensiveComponent will not re-render when count changes, because data prop is
unchanged and wrapped in [Link] 31 . The console log helps verify that.
Key Takeaways
1. Measure First: Use profiling tools (React Profiler, browser performance) to identify actual
bottlenecks.
2. Memoize Wisely: Apply [Link] , useMemo , and useCallback when there is
demonstrated benefit 2 4 . These prevent unnecessary re-renders but add complexity.
3. Correct Dependencies: Always specify hook dependencies accurately to avoid stale closures or
excess updates 4 .
4. Code Split and Lazy Load: Use lazy loading for components not needed at startup to shrink
initial bundle 13 4 .
5. Iterate: Performance tuning is iterative – optimize, test, and refine.
React Router v6
React Router enables client-side navigation in single-page apps. Version 6 introduced a simplified API
and powerful features 32 :
• <Routes> replaces <Switch> for route matching. Each <Route> uses an element prop
for the component.
• Nested routes with <Outlet> , letting child routes render inside parent layouts.
• Hooks: useNavigate (programmatic navigation), useParams (URL parameters),
useLocation , and useMatch .
• Route-based code splitting: Combined with [Link] , you can lazy-load route
components for each path.
• New data APIs (v6.4+): Route loaders and actions for fetching data on navigation, plus
integration with error boundaries for routes.
Example usage:
function Home() {
const navigate = useNavigate();
return <button onClick={() => navigate('/about')}>Go to About</button>;
}
function App() {
12
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="users/:id" element={<UserProfile />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
}
This setup enables seamless navigation without full page reloads, leveraging the History API 32 .
The image below illustrates the SPA concept of navigating between “pages” (browser routes) without
refreshing the browser:
Client-side routing in React (e.g. with React Router) enables seamless navigation without reloading the page
32 .
In React Router v6, nested routes and layout routes are easy to define using <Routes> and
<Outlet> . For example:
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Dashboard />} />
<Route path="settings" element={<Settings />} />
<Route path="users">
<Route index element={<UserList />} />
<Route path=":id" element={<UserProfile />} />
</Route>
</Route>
</Routes>
13
Here, <Layout> contains an <Outlet /> where child routes render. The /users path has nested
routes for listing and detail pages.
Redux Basics
Redux centralizes state in a single store, updated via actions and reducers. In React, use the react-
redux library with <Provider> to give components access to the store, and use useSelector /
useDispatch hooks (or connect HOC).
A reducer is a function (state, action) => newState . Actions are plain objects { type,
payload } . dispatch sends actions to the store.
Redux Thunk is a middleware that allows dispatching functions (thunks) for async logic instead of plain
objects. With Thunk, an action creator can return a function that receives (dispatch, getState) :
Dispatching fetchUser(123) will run this function. Thunks help handle side effects without tying
components directly to async logic.
14
Redux Saga
Redux Saga is an alternative async middleware using ES6 generators. It listens for actions and runs
“saga” generator functions to perform side effects. For example, a watcher saga:
function* fetchUserSaga(action) {
try {
const data = yield call([Link], [Link]);
yield put({ type: 'user/fetchSuccess', payload: data });
} catch (e) {
yield put({ type: 'user/fetchError', error: e });
}
}
function* watchFetchUser() {
yield takeLatest('user/fetchRequest', fetchUserSaga);
}
Redux Toolkit
Redux Toolkit (RTK) is the official, opinionated Redux library that simplifies setup and common tasks.
Key utilities:
• configureStore() : Sets up the store with good defaults (Thunk middleware, Redux DevTools,
etc.) 34 .
• createSlice({ name, initialState, reducers }) : Auto-generates action creators and
action types for a given slice of state 35 .
• createAsyncThunk : Simplifies writing thunks for async logic, automatically dispatching
pending/fulfilled/rejected actions 36 .
• Other utilities: createEntityAdapter , createSelector , etc.
15
);
By using RTK, boilerplate is reduced: action types and creators are auto-generated 37 , and the store
setup is concise:
RTK includes redux-thunk by default 34 (so you can dispatch async thunks). It also warns against
common mistakes (e.g. mutating state) in development by default.
• CSR (Client-Side Rendering): React single-page apps load a minimal HTML and fetch data on the
client.
16
• SSR with [Link]: A page’s HTML is generated on each request by the server. In [Link], you
export an async function getServerSideProps(context) from a page. [Link] runs it on the
server at request time, passes props to the React component, and sends fully-rendered HTML to
the client 38 . Example:
// pages/[Link]
export async function getServerSideProps(context) {
const res = await fetch('[Link]
const profile = await [Link]();
return { props: { profile } };
}
export default function Profile({ profile }) {
return <div>Name: {[Link]}</div>;
}
This fetches data on the server every time. getServerSideProps runs only on the server and never
in the browser 39 . It is ideal for data that changes per request (user-specific data, auth info) 40 .
• SSG (Static Site Generation): Pages are generated at build time. Export
getStaticProps(context) , and [Link] will pre-render the page into static HTML using its
returned props 41 . This HTML and a JSON of props are served to clients. Example:
// pages/[Link]
export async function getStaticProps() {
const res = await fetch('[Link]
const posts = await [Link]();
return { props: { posts } };
}
export default function Posts({ posts }) {
return (
<ul>
{[Link](post => <li key={[Link]}>{[Link]}</li>)}
</ul>
);
}
With SSG, content is generated once (or regenerated in the background if using Incremental Static
Regeneration). Use SSG when data is available at build time and can be cached (e.g. public blog posts)
42 . The static page loads very fast via CDN caching.
• Comparison:
CSR (React SPA) In browser, after load User dashboard behind login, frequent updates
ISR ([Link]) Pre-render + revalidate Mostly static pages with occasional updates
17
[Link] abstracts most configuration. Using getServerSideProps vs getStaticProps depends on
data needs. In both cases, [Link] hydrates the React app on the client (initial HTML is interactive).
Remember to not send sensitive data via props , as they are viewable in the client HTML 39 44 .
Jest allows snapshot tests: it renders a component and saves its output as a snapshot. Future runs
compare against this snapshot to detect unexpected changes 45 .
The first run writes a snapshot file containing the component’s rendered tree. On changes, tests fail if
the output no longer matches the snapshot 45 . This catches unintended UI changes, but be cautious:
snapshots should be reviewed before updating them. As the Jest docs say, “Snapshot tests are useful
whenever you want to make sure your UI does not change unexpectedly” 45 .
React Testing Library focuses on testing components via the user’s perspective 46 . It encourages
querying DOM elements by text, role, or label, rather than implementation details like component
internals.
Key RTL best practices 46 : - Test behavior, not implementation: Find elements like a user would (by
role or label) instead of relying on test IDs or internal state.
- Use screen : It provides queries without needing to destructure from render , making tests
cleaner.
- userEvent over fireEvent : It simulates real user interactions (typing, clicking) more closely 47 .
18
- Async testing: For async UI (API calls), use findBy (returns a Promise) or waitFor to await
changes 48 .
- Organize with describe blocks**: Group related tests for readability.
RTL works well with Mock Service Worker (MSW) or Jest mocks for API requests instead of stubbing
internals.
Combine both: use RTL to assert user-visible behavior, and snapshots via Jest for output. For example,
snapshot-test a component with fixed props, and write interactive tests for user flows.
Ultimately, tests should be maintainable and reflect user behavior, catching regressions without
being overly tied to implementation details.
Component Design
• Small, Focused Components: Each component should have one responsibility. This improves
reusability and testability.
• Container/Presentational Pattern: Separate “container” components (handle state, logic) from
“presentational” ones (focus on rendering UI). This clarifies concerns and makes UI components
reusable with different data.
19
• Hooks & Composition: Prefer composition and hooks over patterns like higher-order
components (HOCs) when possible. Hooks naturally compose logic (e.g. custom hooks) 49 . Use
HOCs or render props for cross-cutting concerns if needed.
• Avoid Mutation: Never mutate state or props directly. Instead, return new objects/arrays.
Immutable updates ensure correct re-rendering (especially with PureComponent or
[Link] ) 50 .
• File Naming: Use clear names (e.g. [Link] for components, [Link] for
hooks).
• Directory Structure: Group files by feature or type (e.g. all user related files in one folder).
Avoid deep nesting.
• Index Files: Use [Link] to re-export related modules for cleaner imports (e.g. import
{ Button } from './components' ).
Performance Tips
• Use lazy loading for heavy components and images (e.g. [Link], <img
loading="lazy"> ).
• Key Prop: Always assign stable, unique keys in lists to help React diff efficiently 30 .
• Avoid Re-Renders: Memoize expensive functions/data and use [Link] to prevent
unnecessary child renders 31 .
• Batching Updates: React batches multiple setState calls in event handlers by default. In
React 18+, updates are batched even in async callbacks.
• Profile Regularly: Keep an eye on performance as features are added. Use Lighthouse and
Profiler in development.
Common Patterns
Security Tips
20
that must happen before the browser repaints. Misusing useLayoutEffect can block rendering, so
default to useEffect unless needed.
Q2: How do useMemo and useCallback differ, and when would you use them?
A: useMemo memoizes a value returned by a computation; useCallback memoizes a function
reference. They both take dependencies. Use useMemo to avoid re-running expensive calculations on
each render. Use useCallback to prevent child components receiving new function props
unnecessarily. For example, passing a callback to a [Link] child should use useCallback so
the child doesn’t re-render because the function changed.
Q3: How can context usage hurt performance, and how would you mitigate it?
A: Every time a context’s value changes, all consuming components re-render. If value is a new
object each render, this triggers many updates. Mitigation techniques include: memoizing the context
value with useMemo , splitting context into multiple contexts for unrelated data, and wrapping
consumers in [Link] . For example, wrap context providers around only the parts of the tree
that need them.
Q6: How does code splitting with [Link] and Suspense work?
A: [Link] lets you dynamically import a component, creating a separate bundle for it 13 . When
the lazy component is rendered, React loads that bundle on-demand. You must wrap lazy components
in <Suspense fallback={...}> . The fallback UI (like a loader) displays while the component is
downloading 13 . This defers loading code not needed immediately, improving initial load performance.
Q7: What is the React Profiler and what information does it give you?
A: The React Profiler (in DevTools and via the <Profiler> API) measures render timings. It tells you
how long each component took to render and how often. The <Profiler> onRender callback
provides actualDuration (render time with memoization) and baseDuration (estimated time
without memo) 2 . This helps identify slow components and verify memo optimizations.
Q8: How do you implement routing in React without a library? Why use React Router instead?
A: Without a router, you can use the History API ( pushState , onpopstate ) and render components
based on [Link] . However, React Router v6 provides a robust solution: it manages URL
parsing, nested routes, parameters, and integrates hooks (like useNavigate ) 32 . It simplifies routing
code, handles edge cases, and supports features like code-splitting by routes. The embedded router
ensures navigation is seamless (no reload) 32 .
Q9: What are the differences between getServerSideProps and getStaticProps in [Link]?
A: getServerSideProps runs on every request on the server, generating a fresh HTML page each
21
time 38 . Use it for data that changes per request (auth, personalized content). getStaticProps runs
at build time (or on a revalidate schedule) and produces static HTML 41 . It’s ideal for public, cacheable
data (blogs, docs). The trade-off is freshness vs performance.
This waits for the element containing “Item” to appear after the (mocked) fetch, asserting correct
behavior. Use findBy to handle the async delay 48 .
Q11: What is the purpose of keys in React lists, and why shouldn’t you use array indices as keys?
A: Keys uniquely identify elements in a list for React’s reconciliation. Stable keys help React match old
and new items, minimizing DOM updates. Using array indices can lead to bugs when the list order
changes: React may think elements haven’t changed (since the index-based key stays same) and fail to
update properly 52 . Always use unique IDs if possible.
Q15: What is Concurrent Rendering, and how does it affect app behavior?
A: Concurrent Rendering (React 18) allows React to interrupt and pause rendering work for better
responsiveness. For example, if the app is busy rendering a large component, concurrent mode can
yield to user input (e.g. a click) and resume rendering later. It also enables transitions and improved
batching. From the developer’s view, you may notice updates appearing out-of-order if wrapped in
22
transitions, but the UI remains interactive. Learning resources explain it as giving the browser back
control between rendering slices 53 .
These questions exemplify the reasoning and explanations expected in a technical interview for a React
developer, with a focus on understanding concepts and their practical use.
Sources: This handbook synthesized content from React’s official documentation and expert articles 3
10 13 16 21 32 38 54 46 45 34 33 , among others, to ensure accuracy and currency. Each
1 4 31 How to Profile and Optimize React Performance Like a Pro | by myHotTake | Medium
[Link]
2 26 – React
[Link]
3 useMemo – React
[Link]
8 react hooks - is useMemo required to manage state via the context API in reactjs? - Stack Overflow
[Link]
13 Code-Splitting – React
[Link]
14 15 16 17 18 createPortal – React
[Link]
19 20 useTransition – React
[Link]
21 22 useDeferredValue – React
[Link]
PerfPerfPerf
[Link]
23
33 React Redux Saga example app.. Click Here to see a live example of… | by Ron Lavit | Medium
[Link]
46 47 48 Best Practices for Using React Testing Library | by Dzmitry Ihnatovich | Medium
[Link]
24