
ReactJS
So far we've sent data down from parent to child. But what if the child needs to communicate back? The answer is passing a callback function as a prop. The child can then call this function to send information back to the parent.
A callback function is a function the parent creates and passes to the child. When something happens in the child, it calls this function, essentially communicating back to the parent:
function Parent() {
const handleChildClick = (message) => {
console.log("Child sent:", message);
};
// Pass the function as a prop
return <Child onClick={handleChildClick} />;
}
function Child({ onClick }) {
// Child can call parent's function when events happen
return (
<button onClick={() => onClick("Hello from child!")}>
Tell Parent
</button>
);
}<details>
<summary>π More Examples</summary>
// Dialog with multiple callbacks
function Dialog({ onConfirm, onCancel }) {
return (
<div className="dialog">
<p>Do you want to continue?</p>
<button onClick={onConfirm}>Yes</button>
<button onClick={onCancel}>Cancel</button>
</div>
);
}
// Parent using the callbacks
function App() {
return (
<Dialog
onConfirm={() => console.log("Confirmed!")}
onCancel={() => console.log("Cancelled")}
/>
);
}</details>
By convention, callback props start with `on` to indicate they handle events:
This makes it immediately clear that a prop is a callback function for handling an event:
function SearchBox({ onSearch }) {
const [query, setQuery] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
// Child calls parent's function with the query
onSearch(query);
};
return (
<form onSubmit={handleSubmit}>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
<button>Search</button>
</form>
);
}<details>
<summary>π More Examples</summary>
// Counter: parent passes callback functions to child
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<CounterButton
label="Increment"
onClick={() => setCount(count + 1)}
/>
<CounterButton
label="Decrement"
onClick={() => setCount(count - 1)}
/>
</div>
);
}
function CounterButton({ label, onClick }) {
return <button onClick={onClick}>{label}</button>;
}</details>
function LoginForm() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
// Call parent callback with form data
onLogin({ email, password });
};
return (
<form onSubmit={handleSubmit}>
<input value={email} onChange={(e) => setEmail(e.target.value)} />
<input value={password} onChange={(e) => setPassword(e.target.value)} type="password" />
<button>Login</button>
</form>
);
}Ready to practice? Challenges | Next: Building Reusable Components
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep β’ Build Real β’ Verify Skills β’ Launch Forward