If you’re new to React you might be a bit confused about the whole data flow concept that you keep hearing about when researching more about React and the way that state and props work.

No worries, as in this article we’ll go over an essential part of the unidirectional data flow of React, which is props; more specifically, the process of passing down a function as a prop to child components.

If you aren’t already familiar with the concept of props, however, I would recommend first checking out this article where you can get a more in-depth explanation of what props are, what’s the data flow in React all about, what role do props play in that process, as well as some code samples as well to help you digest the topic more easily.

Why would we pass a function as a prop in the first place?

As an effect of the unidirectional data flow, we sometimes have to pass certain functions down to children components as props in order to be able to either trigger some side-effects in the parent using state specific to the children components or to simply update the state of the parent from the children components.

That might sound a bit confusing at first, but once you get to see some code samples for the process it should be all clear.

Removing a Task From a List of Tasks

Example Overview

Let’s say that, we have a list of tasks that each rendered as an individual Task component; we also require a delete feature in order to be able to remove a task from the list.

In order to be able to do that, we’ll have to access some identifier that has been passed to the individual task, however, the remove button is inside the component, and as such, we have to trigger the removal of the task from the component itself.

That’s where the only way we can remove the particular task is to pass down a remove function from the main application that takes an id as a parameter to the child component, and then invoke it from the child with the identifier.

Don’t worry if you’re still confused, it should make more sense after we’ll go through some code.

Diving Into Code

We’ll start by creating by defining our mocked tasks, as well as the function that’s going to be used for removing a specific task in our App.js file. We’ll be using the uuid library for generating the unique identifiers for our tasks.

import { v4 as uuidv4 } from "uuid";

...

const [tasks, setTasks] = useState([
  {
    id: uuidv4(),
    content: "Wash the dishes",
  },
  {
    id: uuidv4(),
    content: "Call James",
  },
  {
    id: uuidv4(),
    content: "Prepare the presentation for Wednesday's meeting",
  },
]);

const removeTask = (taskId) => {
  setTasks((tasks) => tasks.filter((task) => task.id !== taskId));
};

Now that we’ve got that set up, let’s create our Task component to be able to render and remove our tasks. We’ll create that inside an index.jsx file under the src/components/Task directory:

import React from "react";

const Task = ({ id, content, removeTask }) => (
  <div className="task">
    <p>{content}</p>
    <button onClick={() => removeTask(id)}>
      Remove Task
    </button>
  </div>
);

export default Task;

The removeTask function that is received as a prop is expected to be the same removeTask function that we’ve defined inside the App.js file. It is invoked with the id that’s been given to a particular task as an argument so we can identify the task that triggered the removal process.

As for the App.js file, it would now look something like this after rendering the list of tasks:

import React, { useState } from "react";
import { v4 as uuidv4 } from "uuid";
import "./App.css";
import Task from "./components/Task";

function App() {
  const [tasks, setTasks] = useState([
    {
      id: uuidv4(),
      content: "Wash the dishes",
    },
    {
      id: uuidv4(),
      content: "Call James",
    },
    {
      id: uuidv4(),
      content: "Prepare the presentation for Wednesday's meeting",
    },
  ]);

  const removeTask = (taskId) => {
    setTasks((tasks) => tasks.filter((task) => task.id !== taskId));
  };

  return (
    <div className="App">
      <div className="tasks-container">
        {tasks.map((task) => (
          <Task
            id={task.id}
            content={task.content}
            removeTask={removeTask}
          />
        ))}
      </div>
    </div>
  );
}

export default App;

Result

After making all the previous changes, our application should be able to render a list of tasks and let us remove any of them:

So now we’ve seen why we would pass functions as props, and how we would do that in the context of removing child components from a list of components (Tasks in our case).

Summary

I hope you’ve enjoyed the read and got a better insight into how and why we would use function props in our components.

Let me know if you think I’ve missed anything by leaving a comment under this article.

Cheers!

👋 Hey, I'm Vlad Mihet
I'm Vlad Mihet, a blogger & Full-Stack Engineer who loves teaching others and helping small businesses develop and improve their technical solutions & digital presence.

💬 Leave a comment

Your email address will not be published.

We will never share your email with anyone else.