Event Handlers as Props

Introduction: Why Pass Event Handlers as Props?

Welcome back! You’ve already learned how to use props to pass data from parent to child components, and how to handle user interactions with event handlers and state. In this lesson, we’ll build on those skills by focusing on a common challenge: how can a child component trigger an action or update state in its parent? This is a key pattern in React Native, especially as your apps grow more complex and interactive.

Imagine you have a product card component with an “Add to Cart” button. When the user taps the button, you want the parent component to update the cart’s state. Passing event handlers as props is the solution. This lesson will show you how to do this in a clear, maintainable way, using practical examples and best practices.

The Problem: Child-to-Parent Communication

Let’s briefly review a challenge you may have encountered: sometimes, a child component needs to let its parent know that something has happened. For example, a button inside a product card might need to tell the parent to increase the quantity of that product in the cart.

If you try to manage all state and logic inside the child, you’ll quickly run into problems. The child doesn’t have access to the parent’s state, and duplicating logic leads to messy, hard-to-maintain code. Instead, it’s best to keep the state and business logic in the parent and let the child “notify” the parent when something happens.

The Solution: Passing Event Handlers as Props

The most effective way to let a child component trigger an action in its parent is to pass an event handler function down as a prop. The parent defines the function, and the child calls it when needed.

Let’s look at a minimal example. Suppose you have a parent component that manages a product’s quantity and a child component that displays the product and includes an “Add to Cart” button.

Here’s the parent component:

import React, { useState } from "react";
import { View } from "react-native";
import ProductCard from "./ProductCard";

const App = () => {
  const [quantity, setQuantity] = useState(0);

  const increaseQuantity = () => {
    setQuantity(quantity + 1);
  };

  return (
    <View>
      <ProductCard quantity={quantity} onIncreaseQuantity={increaseQuantity} />
    </View>
  );
};

export default App;

And here’s the child component:

import React from "react";
import { View, Text, Button } from "react-native";

interface ProductCardProps {
  quantity: number;
  onIncreaseQuantity: () => void;
}

const ProductCard = ({ quantity, onIncreaseQuantity }: ProductCardProps) => (
  <View>
    <Text>Quantity: {quantity}</Text>
    <Button title="Add to Cart" onPress={onIncreaseQuantity} />
  </View>
);

export default ProductCard;

In this setup, the parent (App) owns the state and the logic for increasing the quantity. It passes the increaseQuantity function to the child (ProductCard) as a prop. When the user taps the button, the child calls onIncreaseQuantity, and the parent’s state updates.

This approach keeps your code organized: the parent manages the data, and the child focuses on the UI and user interaction.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal