Passing Data Between React Components With Props

One of React’s core concepts is reusability through composable components. Components allow splitting complex UI into separate, reusable pieces. However, for components to communicate, they need a way to pass data to each other. Enter props.

Props allow passing data from a parent component to a child component. They are like function parameters, but for React components.

Let’s look at a simple example:

// Parent component
const Parent = () => {
  return (
    <Child 
      color="blue"
      onClick={handleClick} 
    />
  );
}

// Child component
const Child = (props) => {
  return <div>{props.color}</div> 
}

The parent component Parent passes two props to the child component Child - a color string and an onClick event handler.

The child component receives these as a props object and can access them as props.color and props.onClick.

Defining Props in a Component

To specify the props a component expects, you can define them in the component function or class:

// Function component
const MyComponent = (props) => {
  // ...
}

// Class component 
class MyComponent extends React.Component {
  // ...
}

React will check that components are passed all the props they expect. This helps catch bugs early.

You can also set default values for props:

const MyComponent = (props) => {
  const color = props.color || 'blue'; 
  // ...
}

Passing Props When Rendering Components

When rendering a component, you pass props like function arguments:

// Parent component
<MyComponent
  title={title}
  content={content}
  author={author}
/>

Access these in the child component through props.

Props are read-only in the child component. The child can’t modify the props - this keeps the data flow unidirectional.

PropTypes for Validation

It’s a good idea to validate props being passed to a component. React provides a PropTypes module to specify prop types:

import PropTypes from 'prop-types';

const MyComponent = (props) => {
  // ...
}

MyComponent.propTypes = {
  title: PropTypes.string.isRequired,
  content: PropTypes.string.isRequired,
  author: PropTypes.shape({
    name: PropTypes.string.isRequired,
    avatar: PropTypes.string
  })
}

This validates props passed to MyComponent. If invalid props are passed, a warning will appear in the console.

When to Use Props vs State

While props allow passing data into a component, state is used to track changes within a component.

Use props for:

  • Data that doesn’t change
  • Initializing component state
  • Passing data from parent to child components

Use state for:

  • Data that changes over time
  • UI state based on user interaction
  • Re-rendering components when data changes

Getting the distinction right takes practice - misusing props and state is a common source of bugs in React.

Conclusion

Props allow different components to work together by passing data between them. Define props a component expects, then pass them when rendering:

// Parent
<Child title="Hello" /> 

// Child
const Child = (props) => {
  <h1>{props.title}</h1>
}

Props allow a unidirectional data flow between parents and children. Combined with state to manage changing data, they make building reusable components much easier in React.