1. Deep Dive: The React Mental Model
1.1 Components are just Functions
Forget "classes" or "instances" for a moment. A React component is simply a JavaScript function. It takes an input (props) and returns an output (JSX). If you call the function with the same props, you should get the exact same UI. This is called idempotency.
// Input: { name: "Alice" }
// Output: <h1>Hello, Alice</h1>
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
1.2 JSX is not HTML
Browsers do not understand JSX. Build tools (Vite/Babel) compile it into standard JavaScript calls.
<div className="box">Hi</div> becomes React.createElement('div', { className: 'box' }, 'Hi').
Why this matters: You can't use HTML keywords like class (reserved in JS) or for. You must use className and htmlFor. You can't return multiple sibling elements without a parent because a function cannot return two values at once.
1.3 The One-Way Data Flow
Data flows down. Parents pass data to children via props. Children cannot modify props. If a child needs to change something, it must ask the parent to do it (via a callback function). This strict hierarchy makes debugging predictable.
1.4 TypeScript & React
We use TypeScript to enforce the "contract" between components. If a component expects a userId, TS ensures you don't forget it.
interface UserCardProps {
name: string;
age?: number; // Optional
role: 'admin' | 'user'; // Union type (Specific strings only)
}
1.5 Industry Standard: The Component Interface
In professional codebases, components are treated as APIs. They must be robust and predictable. A "Senior" component definition often looks like this:
// Real-world Button Interface
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'danger';
size?: 'sm' | 'md' | 'lg';
isLoading?: boolean;
leftIcon?: React.ReactNode;
}
// Note: It extends native HTML attributes so you don't have to manually type 'onClick', 'disabled', etc.
1.4 Industry Standard: Scalable Component Design
To build scalable, high-performance applications, avoid monolithic components. Break UI into:
- Atoms: Buttons, Inputs (Base UI).
- Molecules: SearchBar (Input + Button).
- Organisms: Header (Logo + Nav + SearchBar).
Collaborate with designers to ensure these match the design system.
2. The Setup Challenge
Task: Initialize the Environment
Note on Tools: You might see "Create React App" (CRA) in older job descriptions. It is deprecated. We use Vite because it is significantly faster (uses native ES modules) and easier to configure. However, the React code you write inside src/ is identical.
Do not use a template you found online. Use the CLI.
- Open your terminal.
- Run
npm create vite@latest my-app -- --template react-ts. - Navigate into the folder, install dependencies, and start the server.
- Cleanup: Delete
App.css, delete the contents ofApp.tsx(keep the component shell), and delete the logo files. Start blank.
3. The Build Challenge: "User Card"
Level 1: The Basics
Create a component named UserCard.
- It must accept the following props (define a TypeScript interface):
name(string)role(string, optional - default to "Guest")isActive(boolean)skills(array of strings)
- Logic:
- If
isActiveis true, show a green dot (CSS). If false, red. - Render the list of
skillsusing.map(). - If the user has no skills, display "No skills listed".
- If
Level 2: Senior Constraints (Strict Mode)
- Destructuring: You must destructure props in the function signature, not inside the body.
- Strict Typing: Do not use
any. Ifskillsis an array of objects, define that object type. - Composition: Instead of hardcoding the "Green Dot", create a tiny sub-component
<StatusIndicator isActive={true} />and use it inside the card.
Level 3: Nice to Haves
- Loading State: Add an
isLoadingprop. If true, hide the content and show "Loading user data...". - Event Handling: Add an
onRoleClickcallback prop. When the role text is clicked, fire this function.
4. The Bug Hunt
🐛 Scenario: The Missing Key
The Setup:
const users = ["Alice", "Bob", "Charlie"];
return (
<ul>
{users.map(user => <li>{user}</li>)}
</ul>
);
The Bug: Check your console. You'll see a warning: "Each child in a list should have a unique 'key' prop."
The Task:
- Fix the warning by adding a
key. - Interview Question: Why does React need keys? (Hint: Reconciliation).
- Trap: Why is using
indexas a key (e.g.,map((u, i) => key={i})) dangerous if the list order changes?
5. Test on your own
Verify your Environment
- HMR Check: Change the text color in your CSS while the server is running. Does it update without a full page reload?
- Strict Mode Check: Add a
console.log('Render')inside your component. Open the browser console. Do you see it log twice? (This is React Strict Mode intentionally double-invoking to catch side effects).