What rules need to be followed for hooks?
Assesses fundamental understanding of React conventions, runtime behavior, and memory/performance considerations.
Hiring managers look for precision, avoidance of ambiguous jargon, and ability to explain trade-offs under real production conditions.
You need to follow two rules in order to use hooks,
- Call Hooks only at the top level of your react functions: You should always use hooks at the top level of react function before any early returns. i.e, You shouldn’t call Hooks inside loops, conditions, or nested functions. This will ensure that Hooks are called in the same order each time a component renders and it preserves the state of Hooks between multiple re-renders due to
useStateanduseEffectcalls.
Let's see the difference using an example,
Correct usage::
function UserProfile() {
// Correct: Hooks called at the top level
const [name, setName] = useState('John');
const [country, setCountry] = useState('US');
return (
<div>
<h1>Name: {name}</h1>
<p>Country: {country}</p>
</div>
);
}
Incorrect usage::
function UserProfile() {
const [name, setName] = useState('John');
if (name === 'John') {
// Incorrect: useState is called inside a conditional
const [country, setCountry] = useState('US');
}
return (
<div>
<h1>Name: {name}</h1>
<p>Country: {country}</p> {/* This will throw an error if the name condition isn't met */}
</div>
);
}
The useState hook for the country field is being called conditionally within an if block. This can lead to inconsistent state behavior and may cause hooks to be called in a different order on each re-render.
- Call Hooks from React Functions only: You shouldn’t call Hooks from regular JavaScript functions or class components. Instead, you should call them from either function components or custom hooks.
Let's find the difference of correct and incorrect usage with below examples,
Correct usage::
//Example1:
function Counter() {
// Correct: useState is used inside a functional component
const [count, setCount] = useState(0);
return <div>Counter: {count}</div>;
}
//Example2:
function useFetchData(url) {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then((data) => setData(data));
}, [url]);
return data;
}
function UserProfile() {
// Correct: Using a custom hook here
const user = useFetchData('https://some-api.com/user');
return (
<div>
<h1>{user ? user.name : 'Loading profile...'}</h1>
</div>
);
}
Incorrect usage::
//Example1
function normalFunction() {
// Incorrect: Can't call hooks in normal functions
const [count, setCount] = useState(0);
}
//Example2
function fetchData(url) {
// Incorrect: Hooks can't be used in non-React functions
const [data, setData] = useState(null);
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then((data) => setData(data));
}, [url]);
return data;
}
In the above incorrect usage example, both useState and useEffect are used in non-React functions(normalFunction and fetchData), which is not allowed.
Candidate Response Strategy & Interview Tips
- Start with a concise one-sentence summary: Deliver a direct, confident answer first before expanding into nuances.
- Demonstrate real-world trade-offs: Discuss where this approach excels and when you would avoid it in production systems.
- Discuss complexity & edge cases: Proactively explain time/space complexity or boundary conditions (null values, scale limits).
- Prepare for interviewer follow-ups: Technical hiring panels frequently probe deeper into concurrency, backward compatibility, or alternative libraries.