React
React Best Practices
Master professional React patterns that keep your DataFlow dashboard clean, fast, and maintainable.
After 24 lessons building DataFlow components, you've written React code. But there's a difference between code that works and code that scales. Professional React follows patterns that prevent bugs, speed up development, and make your app maintainable. Best practices aren't rules from a textbook. They're lessons learned from building production apps like Airbnb's booking system or Netflix's video player. These patterns prevent real problems teams face every day.Component Design Principles
Good components follow the same principle as good functions. They do one thing well. A component should have a single responsibility that you can explain in one sentence.The Single Responsibility Principle
If your component handles user data AND manages animations AND fetches API data, split it. Each piece should be its own component or custom hook.
// BAD - Too many responsibilities
function UserProfile() {
const [user, setUser] = useState(null);
const [isAnimating, setIsAnimating] = useState(false);
const [notifications, setNotifications] = useState([]);
// Fetches user data
// Handles notifications
// Manages animations
// Renders UI
return <div>Everything mixed together</div>;
}// GOOD - Single responsibility each
function UserProfile() {
const user = useUserData();
return (
<ProfileCard user={user}>
<UserAvatar src={user.avatar} />
<NotificationBell userId={user.id} />
</ProfileCard>
);
}What just happened?
Each component has one job. ProfileCard handles layout, UserAvatar manages the profile picture, NotificationBell shows alerts. Easier to test, debug, and reuse. Try this: Create a UserCard component that only displays user info, nothing else.
Props and State Management
Props flow down, events flow up. This isn't just a saying - it's the foundation of React architecture. When you break this pattern, debugging becomes nightmare fuel. State should live as close to where it's used as possible. But when multiple components need the same data, lift it to their closest common parent.State Lifting Strategy
If components A and B both need the same state, move it to their parent C. Don't try to share state sideways between siblings - React doesn't work that way.
// GOOD - State lifted to common parent
function Dashboard() {
const [dateRange, setDateRange] = useState('7d');
return (
<div>
<FilterBar onDateChange={setDateRange} />
<ChartSection dateRange={dateRange} />
<DataTable dateRange={dateRange} />
</div>
);
}What just happened?
The Dashboard component owns the dateRange state. FilterBar receives an event handler to update it. Both ChartSection and DataTable receive the current value as props. Single source of truth, predictable data flow.
Performance Optimization
React is fast by default. Most performance problems come from doing too much work, not React being slow. Profile before you optimize - don't guess where the bottlenecks are. The biggest performance killer? Unnecessary re-renders. Every time state changes, React re-renders the component and all its children. That's usually fine, but not when you're rendering 1000+ items.// Optimize expensive calculations
function ExpensiveChart({ data }) {
const processedData = useMemo(() => {
// Heavy computation here
return data.map(item => ({
...item,
trend: calculateTrend(item.values)
}));
}, [data]);
return <Chart data={processedData} />;
}What just happened?
The useMemo hook caches the expensive calculation. Click "Re-render" - the trend calculation only runs when data changes, not on every render. Check your console to see when the calculation actually happens.
Code Organization Patterns
Good code tells a story. When someone opens your component file, they should understand what it does within 10 seconds. Keep the happy path at the top, edge cases at the bottom. Custom hooks extract logic. Components handle rendering. This separation makes both easier to test and reuse across your app.Component Structure
1. Props destructuring
2. Hooks
3. Event handlers
4. Early returns
5. Main JSX
Custom Hook Benefits
• Logic reuse
• Easier testing
• Cleaner components
• Single responsibility
File Organization
One component per file
Co-locate related files
Index.js for clean imports
Naming Conventions
Components: PascalCase
Functions: camelCase
Files match component names
Error Handling and Edge Cases
Users will do things you never expected. Handle the unhappy path gracefully. Show loading states. Handle empty data. Catch errors before they crash your app. Error boundaries catch JavaScript errors anywhere in the component tree. But they only catch errors during rendering, in lifecycle methods, and in constructors. Not in event handlers or async code.// Handle edge cases gracefully
function DataTable({ data, loading, error }) {
if (loading) return <div>Loading transactions...</div>;
if (error) return <div>Failed to load data</div>;
if (!data || data.length === 0) {
return <div>No transactions found</div>;
}
return (
<table>
{/* Happy path - render data */}
</table>
);
}What just happened?
Each state gets its own UI treatment. Early returns keep the code readable - handle edge cases first, then the happy path. Try clicking the buttons to see different states. Users appreciate clear feedback about what's happening.
Testing and Documentation
Code without tests is legacy code the moment you write it. But don't test implementation details - test behavior. If you refactor a component and all tests break, you're testing the wrong things. Good component names are documentation.UserProfileCard tells you more than Card. PropTypes or TypeScript make your component API explicit.
Common Testing Mistakes
Don't test that clicking a button calls setCount(count + 1). Test that clicking the button increases the displayed count. Test what users see, not how you implemented it.
Quiz
1. Your DataFlow dashboard has a ChartSection and TableSection that both need the same filter data. What's the best approach?
2. Which React hook should you use to cache expensive calculations in your DataFlow chart component?
3. What's the best practice for handling edge cases in a React component?
Up Next: Folder Structure
Organize your DataFlow codebase like a professional team - scalable folder patterns that grow with your app.