useState in React: React.useState
vs useState
Explained Like a Pro
In modern React development, we often see two different but seemingly identical ways to use hooks:
// Option 1
const [formData, setFormData] = React.useState({ email: '', name: '' });
// Option 2
import { useState } from 'react';
const [formData, setFormData] = useState({ email: '', name: '' });
Both work perfectly fine — but when and why should you prefer one over the other? Let’s walk through this topic step-by-step and explore its relevance for expert-level React development.
What Is useState
?
useState
is a React hook that lets you add local component state to function components. When called, it returns an array:
const [state, setState] = useState(initialValue);
This hook is essential for keeping your UI in sync with internal values like input fields, visibility flags, counters, etc.
React.useState
vs useState
✅ React.useState
This accesses the hook directly from the React
object. It does not require a named import:
const [count, setCount] = React.useState(0);
Useful when:
- You’re not destructuring
useState
from React. - You want to emphasize where the hook is coming from.
- In code snippets, tools, or playgrounds (e.g., CodePen, CodeSandbox).
✅ useState
(with import)
This accesses the hook by importing it directly:
import { useState } from 'react';
const [count, setCount] = useState(0);
Preferred when:
- Writing modular, clean codebases.
- You want tree-shaking benefits for bundlers.
- Consistent with best practices and modern React style.
Step-by-Step Example: User Registration Form
import React, { useState } from 'react';
export const RegisterForm = () => {
const [formData, setFormData] = useState({
email: '',
name: ''
});
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
return (
<div className="form-card">
<h3>👤 Register</h3>
<input name="name" value={formData.name} onChange={handleChange} placeholder="Your Name" />
<input name="email" value={formData.email} onChange={handleChange} placeholder="Your Email" />
<pre>{JSON.stringify(formData, null, 2)}</pre>
</div>
);
};
Highlights in This Example
- ✅ Destructured
useState
for cleaner syntax. - ✅ Immutability via spread operator.
- ✅ Controlled inputs bound to state.
- ✅ React event typing via TypeScript.
When to Use Which?
Use Case | Recommendation |
---|---|
Quick demo or playground | React.useState |
Production / real-world app | import { useState } |
Code clarity / auto-imports | import { useState } |
Avoiding side effects in bundling | import { useState } |
Tree-Shaking & Performance
When using bundlers like Webpack or Vite, importing only the needed parts (like useState
, useEffect
, etc.) allows for tree-shaking, reducing the final bundle size.
import { useState }
enables better dead-code elimination thanReact.useState
.
Final Thoughts
Both React.useState
and useState
achieve the same functionality. But in expert-level React projects, conventions matter:
- Stick to destructured imports (
useState
,useEffect
, etc.). - Keep your syntax concise and modular.
- Be aware of performance optimization (like tree-shaking).
React isn't just about functionality — it's about readability, performance, and architecture.
#react #hooks #usestate #typescript #frontend #architecture