React Way ⚛️
📋 Table of Contents
- State Immutability 🔒
- Event Handling 🎯
- Conditional Rendering 🔀
- Form Handling 📝
- Side Effects 🌊
- Performance Optimization ⚡
- Children Prop 👶
- Component Composition 🎨
- State Lifting 🔄
- Custom Hooks 🎣
- Key Principles 🗝️
State Immutability 🔒
// Create new arrays/objects for state updates
const [users, setUsers] = useState([{id: 1, name: 'John'}])
// ➕ Adding items
setUsers([...users, {id: 2, name: 'Jane'}])
setUsers(prev => [...prev, newUser])
// ✏️ Updating items
setUsers(users.map(user =>
user.id === 1 ? {...user, name: 'Johnny'} : user
))
// 🔄 Sorting (create new array first!)
setUsers([...users].sort((a, b) => a.name.localeCompare(b.name)))
// 🗑️ Filtering
setUsers(users.filter(user => user.id !== 1))
Event Handling 🎯
// 🎯 Use useCallback for optimization
const handleClick = useCallback((id) => {
setItems(items => items.filter(item => item.id !== id))
}, [])
// 🎛️ State-driven UI
const [isVisible, setIsVisible] = useState(true)
<div style=>Content</div>
// 📤 Event bubbling up
const handleSubmit = (data) => {
onSubmit?.(data) // Pass to parent
}
Conditional Rendering 🔀
// ✅ Clean conditional rendering
{user && user.isActive && <ActiveUser />}
{!user && <GuestUser />}
// 🚪 Early returns in components
if (!user) return <GuestUser />
if (!user.isActive) return <InactiveUser />
return <ActiveUser />
// 🔄 Switch-like pattern
const UserStatus = () => {
switch(user?.status) {
case 'premium': return <PremiumUser />
case 'active': return <ActiveUser />
case 'inactive': return <InactiveUser />
default: return <GuestUser />
}
}
// 🎯 Ternary for simple cases
{isLoading ? <Spinner /> : <Content />}
Form Handling 📝
// 🎛️ Controlled components
const [formData, setFormData] = useState({name: '', email: ''})
const handleChange = (e) => {
setFormData(prev => ({
...prev,
[e.target.name]: e.target.value
}))
}
// 🔄 useReducer for complex forms
const formReducer = (state, action) => {
switch(action.type) {
case 'UPDATE_FIELD':
return {...state, [action.field]: action.value}
case 'RESET':
return initialState
case 'VALIDATE':
return {...state, errors: validateForm(state)}
default:
return state
}
}
// 📋 Form validation
const [errors, setErrors] = useState({})
const validateField = (name, value) => {
setErrors(prev => ({
...prev,
[name]: value.length < 3 ? 'Too short' : ''
}))
}
Side Effects 🌊
// 🎬 useEffect for side effects
useEffect(() => {
localStorage.setItem('data', JSON.stringify(data))
}, [data]) // Only when data changes
// 🚀 Mount effect (API calls)
useEffect(() => {
fetchUserData().then(setUser)
}, []) // Only on mount
// 🧹 Cleanup side effects
useEffect(() => {
const timer = setInterval(() => {}, 1000)
return () => clearInterval(timer) // Cleanup
}, [])
// 👂 Event listeners
useEffect(() => {
const handleScroll = () => setScrollY(window.scrollY)
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
}, [])
Performance Optimization ⚡
// 🧠 Memoization and optimization
const ExpensiveComponent = memo(({items, filter}) => {
const filteredItems = useMemo(() =>
items.filter(item => item.name.includes(filter))
, [items, filter])
return (
<div>
{filteredItems.map(item =>
<MemoizedItem key={item.id} {...item} />
)}
</div>
)
})
// 🔒 memo for component memoization
const MemoizedItem = memo(Item)
// 🎯 useCallback for function memoization
const handleClick = useCallback((id) => {
onItemClick(id)
}, [onItemClick])
// 🚀 useMemo for expensive calculations
const expensiveValue = useMemo(() => {
return data.reduce((acc, item) => acc + item.value, 0)
}, [data])
Children Prop 👶
// 🎁 Basic children usage
const Card = ({ children, title }) => (
<div className="card">
<h3>{title}</h3>
<div className="content">
{children}
</div>
</div>
)
// 📖 Usage
<Card title="User Info">
<p>Name: John</p>
<p>Email: john@example.com</p>
</Card>
// 🔍 Children type checking
const Modal = ({ children, isOpen }) => {
if (!isOpen) return null
return (
<div className="modal-overlay">
<div className="modal">
{children}
</div>
</div>
)
}
// 🎯 Render props pattern
const DataProvider = ({ children, data }) => {
const [loading, setLoading] = useState(true)
return children({ data, loading })
}
// Usage
<DataProvider>
{({ data, loading }) =>
loading ? <Spinner /> : <DataList data={data} />
}
</DataProvider>
// 🔄 Children manipulation
const List = ({ children }) => {
return (
<ul>
{React.Children.map(children, (child, index) =>
<li key={index}>{child}</li>
)}
</ul>
)
}
Component Composition 🎨
// 🧱 Compound components
const Tabs = ({ children, activeTab, onTabChange }) => {
return (
<div className="tabs">
{children}
</div>
)
}
const TabList = ({ children }) => (
<div className="tab-list">{children}</div>
)
const Tab = ({ children, id, isActive, onClick }) => (
<button
className={`tab ${isActive ? 'active' : ''}`}
onClick={() => onClick(id)}
>
{children}
</button>
)
const TabPanels = ({ children }) => (
<div className="tab-panels">{children}</div>
)
const TabPanel = ({ children, isActive }) => (
isActive ? <div className="tab-panel">{children}</div> : null
)
// 📖 Usage
<Tabs activeTab="profile" onTabChange={setActiveTab}>
<TabList>
<Tab id="profile">Profile</Tab>
<Tab id="settings">Settings</Tab>
</TabList>
<TabPanels>
<TabPanel isActive={activeTab === 'profile'}>
<ProfileContent />
</TabPanel>
<TabPanel isActive={activeTab === 'settings'}>
<SettingsContent />
</TabPanel>
</TabPanels>
</Tabs>
// 🎯 Higher-Order Components (HOC)
const withLoading = (Component) => {
return ({ isLoading, ...props }) => {
if (isLoading) return <Spinner />
return <Component {...props} />
}
}
const EnhancedComponent = withLoading(MyComponent)
State Lifting 🔄
// 🏠 Parent manages shared state
const App = () => {
const [user, setUser] = useState(null)
const [cart, setCart] = useState([])
return (
<div>
<Header user={user} cartCount={cart.length} />
<ProductList onAddToCart={(item) => setCart([...cart, item])} />
<Cart items={cart} onRemove={(id) =>
setCart(cart.filter(item => item.id !== id))
} />
</div>
)
}
// 📡 Sibling communication through parent
const SearchBox = ({ onSearch }) => {
const [query, setQuery] = useState('')
return (
<input
value={query}
onChange={(e) => {
setQuery(e.target.value)
onSearch(e.target.value) // Notify parent
}}
/>
)
}
const ResultsList = ({ query, results }) => {
return (
<div>
<h3>Results for: {query}</h3>
{results.map(item => <div key={item.id}>{item.name}</div>)}
</div>
)
}
// Parent coordinates
const SearchPage = () => {
const [query, setQuery] = useState('')
const [results, setResults] = useState([])
const handleSearch = (searchQuery) => {
setQuery(searchQuery)
// Fetch results...
setResults(/* results */)
}
return (
<div>
<SearchBox onSearch={handleSearch} />
<ResultsList query={query} results={results} />
</div>
)
}
Custom Hooks 🎣
// 🎯 Custom hook for API calls
const useApi = (url) => {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(setData)
.catch(setError)
.finally(() => setLoading(false))
}, [url])
return { data, loading, error }
}
// 📱 Custom hook for local storage
const useLocalStorage = (key, defaultValue) => {
const [value, setValue] = useState(() => {
const saved = localStorage.getItem(key)
return saved ? JSON.parse(saved) : defaultValue
})
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value))
}, [key, value])
return [value, setValue]
}
// 🎛️ Custom hook for form handling
const useForm = (initialValues, validationRules) => {
const [values, setValues] = useState(initialValues)
const [errors, setErrors] = useState({})
const handleChange = (name, value) => {
setValues(prev => ({ ...prev, [name]: value }))
// Validate field
if (validationRules[name]) {
const error = validationRules[name](value)
setErrors(prev => ({ ...prev, [name]: error }))
}
}
const reset = () => {
setValues(initialValues)
setErrors({})
}
return { values, errors, handleChange, reset }
}
// 📖 Usage
const { data, loading } = useApi('/api/users')
const [theme, setTheme] = useLocalStorage('theme', 'light')
const { values, errors, handleChange } = useForm(
{ email: '', password: '' },
{
email: (value) => !value.includes('@') ? 'Invalid email' : '',
password: (value) => value.length < 6 ? 'Too short' : ''
}
)
Key Principles 🗝️
🎯 Think in React:
├── 📊 Data flows down (props)
├── 📤 Events bubble up (callbacks)
├── 🎯 Single source of truth
├── 📢 Declarative > Imperative
└── 🧱 Component composition
🔄 State Management:
├── useState -> simple state
├── useReducer -> complex state logic
├── useContext -> shared state (avoid prop drilling)
├── Custom hooks -> reusable stateful logic
└── External libs -> global state (Redux, Zustand)
⚡ Performance:
├── memo() -> component memoization
├── useMemo() -> expensive calculations
├── useCallback() -> function memoization
├── Proper keys -> efficient list rendering
└── Code splitting -> bundle optimization
🧹 Side Effects:
├── useEffect -> DOM interactions, API calls
├── Cleanup functions -> prevent memory leaks
├── Dependency arrays -> control when effects run
└── Custom hooks -> reusable side effect logic
🎨 Component Design:
├── Small, focused components
├── Props for configuration
├── Children for content
├── Composition over inheritance
└── Consistent naming conventions