How to pass a Function as a Prop
What are Props in React
Props or properties in react are a functional argument by which different components communicate with each other.
Props is just a data/information that allows us to pass in JSX tags.
With the help of props, we can pass values like JavaScript objects, arrays or functions, etc.
Props are passed from a parent component to the child component.
Now, if you haven’t understood props yet, it allows us to reuse a component logic dynamically which means that the data or information in the component will not be static.
We’ll understand this with the help of an examples.
Props Syntax
We can use the react props in two different ways and both have their own different syntaxes. The two ways of using props in react app are:
Without destructuring:
The First way of using props is to use them without destructuring.
When using props without destructuring we pass an argument known as props in the function.
We are not declaring the variables before rather we are using them directly into our JSX template i.e., into our <div> element.
The '.courseName' will be defined as a property when calling to 'Course' element.
function Course(props) {
<div>{props.courseName}</div>
}
With destructuring:
In this method, we don’t declare variables first or pass them directly to the JSX template.
Instead of passing the props as an argument we destructured and passed in the variables like the function argument.
function Course({courseName}) {
<div>{courseName}</div>
}
Props are very easy to understand. In this example, we’ll need two things: first one is the main function component (App.js) and a second component (Course) which we is going to render in our App.js component.
import React from "react";
function App() {
return (
<div>
<h1>Guvi Courses</h1>
</div>
);
}
export default App;
Course component, This component will have a prop called courseName which will get its value dynamically after rendering inside the App.js component.
function Course(props) {
return (
<div>
<ul>
<li>{props.courseName}</li>
</ul>
</div>
)
}
Now render the Course component into the App component to pass the props.
Finally your App.js file should look like below:
import React from "react";
function Course(props) {
return (
<div>
<ul>
<li>{props.courseName}</li>
</ul>
</div>
)
}
function App() {
return (
<div>
<h1>Guvi Courses</h1>
<Course courseName="Full Stack Development" />
</div>
);
}
export default App;
In the above code, first we have accessed the information from props in the <li/> element and then after that we are passing a prop called “courseName” in our <Course /> component reading the value of the prop as “Full Stack Development”.
specify default value of prop
Sometimes, we don’t want the props value to be empty or when no value is specified, at that time we can specify a default value just by destructuring and putting = sign and the default value right after the parameter as shown below.
function Course({ courseName, courseType = "development" }) {
...
}
Pass a function with arguments as a Prop
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>
);
}
Pass a function as a Prop from the Child to the parent
If you need to pass a function as a prop from the Child to the Parent
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>
);
}
Adding extra functionality to the function in the Child component
You can also add extra functionality to the function you passed as a prop to the child component.
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.
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>
);
}
Pass onChange event handler to Child component in React
To pass an onChange event handler to a child component
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>
);
}
Pass onChange event handler with parameter to Child component
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>
);
}
Adding extra functionality to the handleChange function
You can also add extra functionality to the function you passed as a prop in the child component.
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.
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>
);
}
Code Snippet
import React from "react";
function Course(props) {
return (
<div>
<ul>
<li>{props.courseName}</li>
</ul>
</div>
)
}
function App() {
return (
<div>
<h1>Guvi Courses</h1>
<Course courseName="Full Stack Development" />
</div>
);
}
export default App;