Last updated: Apr 6, 2024
Reading timeยท5 min
To pass a function as props in React:
import {useState} from 'react'; function Child({handleClick}) { return <button onClick={handleClick}>Increment</button>; } export default function App() { const [count, setCount] = useState(0); function handleClick() { console.log('Function ran in Child component'); setCount(count + 1); } return ( <div> <h2>Count is: {count}</h2> <Child handleClick={handleClick} /> </div> ); }
We passed a function as a prop to a child component in React.
<Child handleClick={handleClick} />
If you pass the result of calling the function, e.g.
handleClick={handleClick()}
, then it would get invoked immediately when the
page loads, which is not what we want.
If you need to pass a function as props in React TypeScript, check out the following tutorial.
If you want to pass a parameter to the function that you are passing as a prop, use an inline arrow function.
import {useState} from 'react'; function Child({handleClick}) { return <button onClick={handleClick}>Increment</button>; } export default function App() { const [count, setCount] = useState(0); function handleClick(event, num) { console.log('Function ran in Child component'); setCount(count + num); } return ( <div> <h2>Count is: {count}</h2> <Child handleClick={event => handleClick(event, 100)} /> </div> ); }
We passed a parameter to the handleClick
function when passing it as a prop to
the Child
component. However, note that we are still passing a function as a
prop, and not the result of calling one.
event
parameter might not be needed for your use case. All event handlers get called with the event
object as the first argument, so we had to pass it to the function in this example.If you need to pass a function as a prop from the Child to the Parent component:
import {useState} from 'react'; function Child({handleClick}) { const logger = () => { console.log('Function defined in Child'); }; return ( <div> <button onClick={event => handleClick(logger)}>Click</button> </div> ); } export default function Parent() { const [count, setCount] = useState(0); const handleClick = func => { // ๐๏ธ call the function the Child component passed func(); setCount(count => count + 1); }; return ( <div> <Child handleClick={handleClick} /> <h2>Count: {count}</h2> </div> ); }
The handleClick
function in the Parent component takes another function as a
parameter.
We passed the function as a prop to the Child component and called it, passing
it the logger()
function.
Everything handleClick
is invoked, we call the function from the Child
component and update the state.
I've also written a detailed guide on how to call a child function from a parent component.
You can also add extra functionality to the function you passed as a prop to the child component.
import {useState} from 'react'; function Child({handleClick}) { // ๐๏ธ wrap passed in function function wrapHandleClick(event) { // ๐๏ธ your logic before console.log('Child called handleClick'); handleClick(event); // ๐๏ธ your logic after } return <button onClick={wrapHandleClick}>Increment</button>; } export default function App() { const [count, setCount] = useState(0); function handleClick(event, num) { setCount(count + num); } return ( <div> <h2>Count is: {count}</h2> <Child handleClick={event => handleClick(event, 100)} /> </div> ); }
handleClick
function into another function where we can run some extra logic before or after calling it.This is useful when you have to await the return value of a Promise or run some logic based on the return value of the passed function.
To pass an onChange event handler to a child component:
onChange
prop on the input field in the child.import {useState} from 'react'; function Child({handleChange}) { return ( <input id="message" name="message" onChange={handleChange} /> ); } export default function App() { const [message, setMessage] = useState(''); function handleChange(event) { setMessage(event.target.value); } return ( <div> <Child handleChange={handleChange} /> <h2>Message is: {message}</h2> </div> ); }
We passed a handleChange
function to a child component.
If you pass the result of calling the function, e.g.
handleChange={handleChange()}
, then it would get invoked immediately on page
load, which is not what we want.
If you want to pass a parameter to the function that you are passing as a prop, use an inline arrow function.
import {useState} from 'react'; function Child({handleChange}) { return ( <input id="message" name="message" onChange={handleChange} /> ); } export default function App() { const [message, setMessage] = useState(''); function handleChange(event, anotherParam) { console.log(anotherParam); setMessage(event.target.value); } return ( <div> <Child handleChange={event => handleChange(event, 'another param')} /> <h2>Message is: {message}</h2> </div> ); }
We passed a parameter to the handleChange
function when passing it as a prop
to the Child
component. However, note that we are still passing a function as
a prop, and not the result of calling one.
handleChange
functionYou can also add extra functionality to the function you passed as a prop in the child component.
import {useState} from 'react'; function Child({handleChange}) { function wrapHandleChange(event) { console.log('Child triggered onChange'); // ๐๏ธ your logic before handleChange(event); // ๐๏ธ your logic after } return ( <input id="message" name="message" onChange={wrapHandleChange} autoComplete="off" /> ); } export default function App() { const [message, setMessage] = useState(''); function handleChange(event) { setMessage(event.target.value); } return ( <div> <Child handleChange={handleChange} /> <h2>Message is: {message}</h2> </div> ); }
We wrapped the handleChange
function into another function where we can run
some extra logic before calling it or after.
This is useful when you have to await the return value of a Promise or run some logic based on the value of the input field.