Codepath

Components

React Components

Overview

Components are the building blocks of React applications. They let us create independent, reusable pieces of code that we can combine to build complex user interfaces.

Think of components like LEGO blocks - each piece is self-contained and can be connected with other pieces to build something bigger.

What is a Component?

Components are JavaScript functions that return pieces of UI. Some common examples include:

  • <Navbar /> - Navigation menu
  • <Header /> - Page header
  • <Avatar /> - User profile picture
  • <Container>...</Container> - Layout wrapper

⚠️ Important: React component names must start with a capital letter. This is how React tells the difference between custom components and regular HTML elements.

// ❌ Bad: React will think this is an HTML element
function header() {
  return <h1>Hello World</h1>;
}

// ✅ Good: React knows this is a custom component
function Header() {
  return <h1>Hello World</h1>;
}

Creating Components

The modern way to create React components is using functions:

function Header(props) {
  return (
    <div>
      <h1>Hello, {props.name}</h1>
    </div>
  );
}

Learn more about components in the React Component Lifecycle guide.

💡 Tip: Since React 16.8, we use hooks to add features like state management to functional components. While you might see older code using class components, functional components are now the recommended approach.

Passing Data with Props

Components receive data through parameters called props (short for properties). Props let parent components send data to their children:

// Passing a prop to our Header component
<Header name="CodePath" />

// The Header component using the prop
function Header(props) {
  return <h1>Hello, {props.name}</h1>;
}

Props can include different types of data:

<Profile 
  name="CodePath"               // String
  age={25}                     // Number
  isActive={true}              // Boolean
  user={{ id: 1, role: 'admin' }}  // Object
  onFollow={() => alert('Followed!')}  // Function
/>

The One Rule of Props

Props follow one important rule: A component must never modify its own props.

Think of props like arguments in a math function - the function uses the arguments but doesn't change them:

// ❌ Bad: Modifying props
function BadComponent(props) {
  props.count = props.count + 1; // Don't do this!
  return <div>{props.count}</div>;
}

// ✅ Good: Using props without modifying them
function GoodComponent(props) {
  return <div>{props.count}</div>;
}

Working with Component Data

The below example shows how data flows from a parent component to a child component. The useState hook is used to manage the state of the parent component.

function ParentComponent() {
  const [count, setCount] = useState(0);

  return (
    <ChildComponent 
      count={count}
      onIncrement={() => setCount(count + 1)}
    />
  );
}

function ChildComponent(props) {
  return (
    <button onClick={props.onIncrement}>
      Count: {props.count}
    </button>
  );
}

Learn more about React state management in the React useState Hook and React Expanded State Management guides.

Component Lifecycle

Modern React uses hooks to manage component lifecycle events. The most common hooks are:

  • useState - For managing component state
  • useEffect - For handling side effects
function UserProfile() {
  // State management
  const [user, setUser] = useState(null);

  // Lifecycle management
  useEffect(() => {
    // This runs after component mounts
    fetchUserData().then(data => setUser(data));

    // This runs before component unmounts
    return () => {
      saveUserData(user);
    };
  }, []);

  if (!user) return <div>Loading...</div>;

  return <div>Welcome, {user.name}!</div>;
}

Learn more in the React Component Lifecycle guide.

Additional Resources

Fork me on GitHub