Functional Components And Passing Props

Practice creating a functional component, passing props from a parent to a child, and even passing down functions as props. Follow George Polya's four-step problem-solving approach to build stronger React fundamentals.

Understanding the Challenge

In this assignment, you will create a React component named BaseStats and pass data (props) to it from an App parent component. You will also learn how to pass a function as a prop to allow the child component to trigger logic defined in the parent.

Essentially, we want to display basic statistics (like HP, Attack, Defense, Speed) in a child component. The numbers (and even the function that pops up an alert) will come from the parent. This is how React components communicate.

A Whiteboard Plan

Here's a quick outline (imagine drawing it on a whiteboard) for how to proceed:

By following these steps, you ensure data flow from parent to child, and event triggering from child to parent.

Carrying Out the Plan

Below are the steps translated into code, along with pseudocode and additional guidance. Let's walk through it!

Expected Input:

Expected Output:

Basic Working Solution

Let's start with a bare-bones version of your BaseStats component and how it connects to App.


// src/BaseStats.jsx
/*
  // Pseudocode:
  // 1. Functional component named BaseStats
  // 2. Return a <div> with a className and an <h1>

  import './BaseStats.css'; // If you have styles

  function BaseStats(props) {
    return (
      <div className="base-stats">
        <h1>BaseStats</h1>
      </div>
    );
  }

  export default BaseStats;
*/
        

In the next step, we add stats and pass them from the parent. Let's see how that works in App.jsx.


// src/App.jsx
/*
  // Pseudocode:
  // 1. Define baseStats object with numeric values
  // 2. Pass baseStats as a prop called stats to BaseStats
  // 3. Render BaseStats below Showcase

  import Showcase from './Showcase';
  import BaseStats from './BaseStats';

  function App() {
    const baseStats = {
      hp: 45,
      attack: 49,
      defense: 49,
      spAttack: 65,
      spDef: 65,
      speed: 45,
    };

    return (
      <div>
        <Showcase />
        <BaseStats stats={baseStats} />
      </div>
    );
  }

  export default App;
*/
        

Enhanced Working Solution

Now let's populate the BaseStats component with the actual table and destructure props. We'll also pass down a function from the parent to demonstrate how a child can trigger parent logic.

Step by Step Directions


// src/App.jsx
/*
  // Additional steps: add a function handleClick that alerts the special stats
  // Then pass handleClick as clicker={handleClick} to BaseStats

  import Showcase from './Showcase';
  import BaseStats from './BaseStats';

  function App() {
    const baseStats = {
      hp: 45,
      attack: 49,
      defense: 49,
      spAttack: 65,
      spDef: 65,
      speed: 45,
    };

    function handleClick() {
      alert(
        `Special Stats\n\tSpecial Attack: ${baseStats.spAttack}\n\tSpecial Defense: ${baseStats.spDef}`
      );
    }

    return (
      <div>
        <Showcase />

        <BaseStats
          stats={baseStats}
          clicker={handleClick}
        />
      </div>
    );
  }

  export default App;
*/
          

// src/BaseStats.jsx
/*
  // 1. Import a CSS file for your styles (BaseStats.css)
  // 2. Destructure stats from props
  // 3. Destructure clicker (the function) from props
  // 4. Render a table with hp, attack, defense, speed
  // 5. Above the table, add a button that calls clicker onClick
*/

import './BaseStats.css';

function BaseStats({ stats: { hp, attack, defense, speed }, clicker }) {
  return (
    <div className="base-stats">
      <h1>BaseStats</h1>

      <button className="sp-stats" onClick={clicker}>
        Check Special Stats
      </button>

      <table>
        <tbody>
          <tr>
            <td>Hit Points</td>
            <td>{hp}</td>
          </tr>
          <tr>
            <td>Attack</td>
            <td>{attack}</td>
          </tr>
          <tr>
            <td>Defense</td>
            <td>{defense}</td>
          </tr>
          <tr>
            <td>Speed</td>
            <td>{speed}</td>
          </tr>
        </tbody>
      </table>
    </div>
  );
}

export default BaseStats;
          

// src/BaseStats.css
/*
  .base-stats {
    border: 2px solid black;
    padding: 12px;
    margin: 16px;
    width: 300px;
  }

  .sp-stats {
    background-color: #8a2be2;
    color: #fff;
    border: none;
    padding: 8px 12px;
    cursor: pointer;
  }

  .sp-stats:hover {
    background-color: #5d2092;
  }

  table {
    width: 100%;
    margin-top: 12px;
  }

  td {
    padding: 4px;
  }
*/
          

With this configuration, clicking the "Check Special Stats" button will trigger the handleClick function in the parent component, popping up an alert with spAttack and spDef.

Explanations for New Developers

  • Destructuring: BaseStats({ stats: { hp, attack, defense, speed }, clicker }) means you extract hp, attack, etc., directly from props.stats.
  • Passing Functions as Props: The child references clicker, but the actual logic lives in the parent. This is essential for parent-child communication in React.
  • DRY Principle (Don't Repeat Yourself): By destructuring, you avoid typing props.stats everywhere.

Evaluate and Reflect

Open your browser to the URL shown by npm run dev (usually http://localhost:5173). Confirm:

If everything displays and works, you have successfully passed both values and a function from a parent component to a child component! This pattern is a backbone of React for keeping data flow clear and consistent.

Real World Analogy

Think of a parent giving a child a set of instructions (data) and a phone number (function). The child can read the instructions (stats) and call the number (trigger the function) to ask for help or do something the parent controls. React props behave similarly: the parent always retains ultimate ownership, but the child can access and trigger them.

Further Examples

Conclusion

You have successfully learned how to pass both plain data and functions as props from a parent component to a child component, destructure props, and handle events that call parent-defined logic. This knowledge is integral to building modular, maintainable React apps.

Happy coding, and may your stat tables always be well-structured!