Control Props Pattern
📖 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
1import React, { useState } from 'react';23// A Toggle component that can be Controlled or Uncontrolled4function Toggle({ on, onChange, defaultOn = false }) {5 // 1. Internal state (used if uncontrolled)6 const [internalOn, setInternalOn] = useState(defaultOn);78 // 2. Determine if we are controlled9 const isControlled = on !== undefined;10 const stateOn = isControlled ? on : internalOn;1112 const handleToggle = () => {13 if (!isControlled) {14 setInternalOn(!stateOn);15 }16 // 3. Always notify the parent17 if (onChange) {18 onChange(!stateOn);19 }20 };2122 return (23 <button24 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}3132// Usage33function App() {34 const [bothOn, setBothOn] = useState(false);3536 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>4243 <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 off50 </button>51 </div>52 </div>53 </div>54 );55}
🏋️ Practice Exercise
- Implement a 'Counter' component that uses the Control Props pattern.
- Build a 'SearchSelect' component where the parent can optionally control the selected item and the search query.
- Research the
useControlledhook pattern used in libraries like Material UI or Reach UI. - 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
onChangecallback 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