JavaScript & React Errors Handbook
Why common JavaScript and React errors happen and how to fix them: undefined properties, non-functions, const reassignment, re-renders, hooks rules, try/catch and more.
On this page
The Complete Beginner-to-Professional Interview Guide#
If you can understand why an error happens, you can solve almost any bug.
This document teaches JavaScript and React errors like a senior engineer mentoring a junior developer.
Table of Contents
- Introduction
- What Actually Happens When Code Runs
- JavaScript Error Lifecycle
- Types of JavaScript Errors
- Syntax Errors
- Runtime Errors
- Logical Errors
- Error Objects
- Throwing Custom Errors
- try...catch...finally
- Promise Error Handling
- Async/Await Errors
- Browser Errors
- Node.js Errors
- Common JavaScript Errors
- React Rendering Lifecycle
- React Error Categories
- React Render Errors
- React Hook Errors
- State Errors
- Props Errors
- Event Errors
- Async React Errors
- API Errors
- React Error Boundaries
- React Strict Mode
- Common React Interview Questions
- Debugging Workflow
- Production Error Handling
- Best Practices
- Senior Engineer Checklist
Introduction
Many beginners think errors are bad.
Professional engineers think differently.
An error is simply the program telling you:
"I expected one thing, but received another."
Learning errors is learning how JavaScript thinks.
How JavaScript Executes Code
Before understanding errors, understand execution.
Source Code
↓
Parser
↓
Abstract Syntax Tree (AST)
↓
Compilation
↓
Execution
↓
Memory Allocation
↓
Garbage Collection
Errors can happen during any stage.
| Stage | Possible Error |
|---|---|
| Parsing | SyntaxError |
| Compilation | ReferenceError |
| Runtime | TypeError |
| Logic | Wrong Output |
Three Categories of Errors
Errors
├── Syntax Errors
├── Runtime Errors
└── Logical Errors
Every bug belongs somewhere here.
1. Syntax Errors
These happen before your code even starts.
Example
const name = ;
Output
SyntaxError:
Unexpected token ';'
Why?
The parser cannot understand your code.
More Examples
Missing bracket
if (true {
}
Missing comma
const user = {
name: "John"
age: 20
}
Missing quote
const a = "Hello;
2. Runtime Errors
The code starts successfully.
Later, something unexpected happens.
Example
const user = null;
console.log(user.name);
Output
TypeError:
Cannot read properties of null
The parser is happy.
The runtime is not.
3. Logical Errors
These are the hardest.
No error message.
Wrong result.
Example
function add(a, b) {
return a - b;
}
add(5, 2);
Output
3
Expected
7
JavaScript thinks your code is valid.
Humans know it's wrong.
JavaScript Error Object
Every error extends Error.
const error = new Error("Something went wrong");
Properties
error.name;
error.message;
error.stack;
error.cause;
Example
try {
throw new Error("Login failed");
} catch (error) {
console.log(error.name);
console.log(error.message);
console.log(error.stack);
}
Built-in JavaScript Errors
Error
├── SyntaxError
├── TypeError
├── ReferenceError
├── RangeError
├── URIError
├── EvalError
├── AggregateError
Let's learn each.
ReferenceError
Variable doesn't exist.
console.log(user);
Output
ReferenceError:
user is not defined
Another example
function test() {}
console.log(a);
TypeError
Wrong type.
Most common interview question.
const user = null;
user.name;
Output
Cannot read properties of null
Another
const age = 20;
age();
Output
age is not a function
RangeError
Value outside allowed range.
new Array(-1);
Output
RangeError
Another
Number(1).toFixed(200);
URIError
Wrong URI encoding.
decodeURIComponent("%");
AggregateError
Used with Promise.any()
Promise.any([Promise.reject(), Promise.reject()]);
Throwing Custom Errors
Instead of waiting for JavaScript...
Throw your own.
function divide(a, b) {
if (b === 0) {
throw new Error("Cannot divide by zero");
}
return a / b;
}
try...catch
try
↓
Exception
↓
catch
↓
finally
Example
try {
riskyOperation();
} catch (error) {
console.error(error);
} finally {
console.log("Always executes");
}
finally
Runs no matter what.
Perfect for
- Closing database connections
- Hiding loading spinner
- Cleaning resources
Promise Errors
Without catch()
fetch("/api");
Output
Unhandled Promise Rejection
Correct
fetch("/api")
.then(...)
.catch(error=>{
});
Async Await Errors
Wrong
await fetch(url);
Correct
try {
await fetch(url);
} catch (error) {}
Common JavaScript Errors
Cannot read properties of undefined#
user.name;
Fix
user?.name;
x is not a function#
const age = 20;
age();
Assignment to constant variable#
const a = 10;
a = 20;
Unexpected token#
Usually
- Missing comma
- Missing bracket
- Wrong quote
React
React introduces another layer.
JavaScript
↓
React
↓
Browser
Errors can happen at all three layers.
React Rendering
Every component goes through
Mount
↓
Render
↓
Commit
↓
Effects
↓
Re-render
↓
Unmount
Knowing this helps explain almost every React bug.
React Error Categories
React Errors
├── Render Errors
├── Hook Errors
├── State Errors
├── Props Errors
├── Event Errors
├── Async Errors
├── Rendering Loops
├── Performance Errors
Render Errors
Example
const user = null;
return <h1>{user.name}</h1>;
Output
Cannot read properties of null
Fix
{
user?.name;
}
React Hook Errors
Most famous.
Invalid hook call
Why?
Hooks must
- Be at top level
- Never inside loops
- Never inside conditions
- Never inside nested functions
Wrong
if (user) {
useEffect(() => {}, []);
}
Correct
useEffect(() => {
if (user) {
}
}, [user]);
Too Many Re-renders
Example
function App() {
const [count, setCount] = useState(0);
setCount(1);
}
Infinite loop.
Fix
Move inside
useEffect
or
Event
Maximum Update Depth Exceeded
Usually
useEffect(() => {
setCount(count + 1);
}, [count]);
Loop forever.
Missing Dependency
Example
useEffect(() => {
console.log(user);
}, []);
ESLint
Missing dependency
Correct
[user];
State Mutation
Wrong
user.name = "John";
setUser(user);
Correct
setUser({
...user,
name: "John",
});
Props Errors
Wrong
<Profile />
Inside
props.user.name;
Output
Cannot read properties of undefined
Key Errors
Wrong
users.map((user) => <div></div>);
Output
Each child should have unique key
Correct
key={user.id}
Never use index unless necessary.
Controlled vs Uncontrolled
Wrong
<input value={undefined} />
Later
value = "John";
Warning
Changing uncontrolled input...
Event Errors
Wrong
<button onClick={handle()}>
Correct
<button onClick={handle}>
Async Component Errors
Example
const data = await fetch();
Component renders before data exists.
Solution
Loading state
if (isLoading) {
return <Loader />;
}
API Errors
Never trust APIs.
Always check
Loading
↓
Success
↓
Error
↓
Empty
Example
if (error) {
return <Error />;
}
if (loading) {
return <Loader />;
}
if (!data) {
return <Empty />;
}
Error Boundaries
React can recover from rendering errors.
Example
<ErrorBoundary>
<App />
</ErrorBoundary>
They catch
- Render errors
- Lifecycle errors
They DO NOT catch
- Event handlers
- Async functions
- API failures
Strict Mode
React intentionally renders twice in development.
Not a bug.
Purpose
- Detect side effects
- Detect unsafe code
- Prepare concurrent rendering
Debugging Workflow
A senior engineer never randomly changes code.
Follow this process.
Read Error
↓
Read Stack Trace
↓
Locate File
↓
Locate Line
↓
Understand Cause
↓
Fix Root Problem
↓
Test Again
Never skip reading the stack trace.
Reading Stack Traces
Example
TypeError
↓
Profile.jsx
↓
Line 24
↓
render()
↓
App.jsx
Always start from the first line inside your code, not React internals.
Console Methods
console.log()
console.error()
console.warn()
console.table()
console.dir()
console.trace()
console.time()
console.timeEnd()
console.group()
console.groupEnd()
Professional debugging relies on more than console.log.
Production Error Handling
Instead of
Application crashed
Show
Something went wrong.
Please try again.
Log the real error to monitoring software.
Examples
- Sentry
- Bugsnag
- Rollbar
Common Interview Questions
Why do React components re-render?#
Because
- State changed
- Props changed
- Parent rendered
- Context changed
Difference between throw and console.error?#
throw
↓
Stops execution
console.error
↓
Only logs
Difference between null and undefined?#
undefined
↓
Not assigned
null
↓
Intentionally empty
Why is mutation bad?#
React compares references.
Mutation keeps the same reference.
React may not detect changes.
Why should hooks stay at top level?#
React depends on the order of hook calls between renders. Conditional hooks change that order and break React's internal state mapping.
Why use Error Boundaries?#
To prevent a single component crash from taking down the entire React application UI.
Best Practices
✅ Read the complete error message.
✅ Read the stack trace.
✅ Understand the root cause before changing code.
✅ Validate API responses.
✅ Prefer optional chaining (?.) when values can be absent.
✅ Throw meaningful custom errors.
✅ Never ignore rejected promises.
✅ Keep state immutable.
✅ Use TypeScript to catch many errors before runtime.
✅ Use ESLint and Prettier to catch mistakes early.
✅ Write small, testable functions.
Senior Engineer Checklist
Before asking for help, verify the following:
- Did I read the entire error message?
- Did I read the stack trace?
- Do I know which file failed?
- Do I know which line failed?
- Is the value
nullorundefined? - Am I mutating state?
- Are my hooks called correctly?
- Does every list item have a unique key?
- Did I handle loading, success, empty, and error states?
- Did I wrap asynchronous code with proper error handling?
- Can I reproduce the issue consistently?
- Have I fixed the root cause instead of hiding the symptom?
Final Advice
The strongest engineers are not the ones who memorize every error message—they are the ones who can reason from first principles.
Whenever you encounter an error:
- Read the full message.
- Read the stack trace.
- Reproduce the issue.
- Understand why it happened.
- Fix the underlying cause.
- Verify the fix with tests.
If you build this habit early, you'll debug faster, perform better in interviews, and write more reliable software throughout your career.