Skip to main content

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>
  );
}

 

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;