Control Props Pattern

0/3 in this phase0/36 across the roadmap

📖 Concept

Control Props is a pattern used to create components that can be either uncontrolled (managing their own state) or controlled (state managed by the parent).

This is exactly how standard HTML inputs work in React. If you pass a value prop, it becomes controlled. If you don't, it's uncontrolled.

Why use it? It gives users of your component ultimate power. They can let the component handle its own business for 90% of cases, but "take over" the state when they need to sync it with other parts of the app.

💻 Code Example

codeTap to expand ⛶
1import React, { useState } from 'react';
2
3// A Toggle component that can be Controlled or Uncontrolled
4function Toggle({ on, onChange, defaultOn = false }) {
5 // 1. Internal state (used if uncontrolled)
6 const [internalOn, setInternalOn] = useState(defaultOn);
7
8 // 2. Determine if we are controlled
9 const isControlled = on !== undefined;
10 const stateOn = isControlled ? on : internalOn;
11
12 const handleToggle = () => {
13 if (!isControlled) {
14 setInternalOn(!stateOn);
15 }
16 // 3. Always notify the parent
17 if (onChange) {
18 onChange(!stateOn);
19 }
20 };
21
22 return (
23 <button
24 onClick={handleToggle}
25 className={`px-4 py-2 rounded ${stateOn ? 'bg-green-500' : 'bg-gray-300'}`}
26 >
27 {stateOn ? 'ON' : 'OFF'}
28 </button>
29 );
30}
31
32// Usage
33function App() {
34 const [bothOn, setBothOn] = useState(false);
35
36 return (
37 <div className="space-y-4 p-10">
38 <div>
39 <p>Uncontrolled (Handles its own state):</p>
40 <Toggle onChange={on => console.log('Toggled to:', on)} />
41 </div>
42
43 <div>
44 <p>Controlled (Parent forces state):</p>
45 <div className="space-x-2">
46 <Toggle on={bothOn} onChange={setBothOn} />
47 <Toggle on={bothOn} onChange={setBothOn} />
48 <button onClick={() => setBothOn(false)} className="underline text-sm">
49 Turn both off
50 </button>
51 </div>
52 </div>
53 </div>
54 );
55}

🏋️ Practice Exercise

  1. Implement a 'Counter' component that uses the Control Props pattern.
  2. Build a 'SearchSelect' component where the parent can optionally control the selected item and the search query.
  3. Research the useControlled hook pattern used in libraries like Material UI or Reach UI.
  4. Explain why you might want to avoid making EVERY prop a control prop.

⚠️ Common Mistakes

  • Not handling the transition between controlled and uncontrolled correctly (React will warn if a component changes from one to the other).

  • Forgetting to call the onChange callback in the uncontrolled case.

  • Creating complex 'sync' logic when a simple 'key' prop would have sufficed to reset internal state.

💼 Interview Questions

🎤 Mock Interview

Practice a live interview for Control Props Pattern