ReactJS tutorial

Open ReactJS lesson pages →

Performance Hooks in Refactoring

Performance Hooks

1

Study notes

Measure repeated work before adding memoization.

Read the explanation, run the worked example, then complete the matching Examples and Assignments tabs. Your original materials remain available alongside these notes.

Understand the idea

Start with correct rendering and clear state ownership. useMemo can cache a calculated value; useCallback can retain a function identity; memo can skip a child render when its props are unchanged. These tools do not fix incorrect dependencies or state mutations. Small calculations usually do not need them.

Your API-with-headers example belongs to effect synchronization, not memoization: do not fetch inside useMemo. For memoized children, a newly created object or function prop can prevent a skip. Measure with React DevTools Profiler before and after. If a project uses React Compiler, some memoization may be handled automatically; understand the underlying data flow either way.

Data / props ↓ JavaScript expression ↓ JSX elements ↓ Visible UI
Trace the values through each step before changing the code.

Run the example

Use a separate React practice project with a Node.js version supported by Vite. Create it once with these commands, then use its development URL. Do not paste this into the Edupoly website’s own source files.

npm create vite@latest react-practice -- --template react
cd react-practice
npm install
npm run dev

Replace src/App.jsx with the following complete example. Keep Vite’s generated src/main.jsx entry point.

src/App.jsx

import { memo, useCallback, useMemo, useState } from 'react';
const students = [{id: 1, name: 'Asha'}, {id: 2, name: 'Ravi'}];
const Results = memo(function Results({items, onSelect}) {
  return <ul>{items.map(item => <li key={item.id}><button onClick={() => onSelect(item.name)}>{item.name}</button></li>)}</ul>;
});
export default function App() {
  const [query, setQuery] = useState('');
  const [selected, setSelected] = useState('');
  const visible = useMemo(() => students.filter(s => s.name.toLowerCase().includes(query.toLowerCase())), [query]);
  const select = useCallback(name => setSelected(name), []);
  return <main><label>Search <input value={query} onChange={e => setQuery(e.target.value)} /></label><Results items={visible} onSelect={select} /><p>Selected: {selected}</p></main>;
}

Expected result

Typing “rav” filters to Ravi; selecting Ravi changes the selected label. Use the Profiler to inspect render behavior rather than assuming a speedup.

Apply this to your assignments

Apply memo to a measured expensive child in your refactored app. Compare before/after renders. Use the lifecycle lesson’s fetch pattern for the error-handling assignment: test rejected requests, non-2xx responses, and unmounting.

Your existing examples

  • 1.API Calls with headers using fetch inside useEffect hook
  • 2.Performance with useCallback
  • 3.Performance with useMemo

Open the Examples tab to run or inspect these supplied projects. Their original links are preserved.

Open Assignments for your complete original worksheet and submission controls.

Common mistakes

Dependencies must include reactive values read by a callback. Memoization is an optimization, not a correctness guarantee.

Check your understanding

  1. Predict the output before running the example, then compare it with the result panel.
  2. Explain which value each expression reads and which action changes it.
  3. Try the boundary cases listed in the practice task and record what you observe.
  4. Rebuild one matching assignment without copying, then compare behavior with the original example.

Reference

Official documentation for this topic · Vite setup requirements