AlgoDaily

React Components and Props

Read at your own pace. Code execution, quizzes, progress tracking, and the AI tutor are available in the interactive view with JavaScript enabled.

Introduction to React Components

Introduction to React Components

In React, components are the building blocks of a user interface. They represent a piece of the UI that can be reused throughout the application.

Just like LEGO bricks can be combined in various ways to create different structures, React components can be combined to create complex UIs.

Components in React can be of two types: functional components and class components. Functional components are defined as JavaScript functions, while class components are defined as ES6 classes that extend the React.Component class.

Here's an example of a functional component in React:

import React from 'react';

function Greeting() {
  return (
    <div>
      <h2>Hello, World!</h2>
      <p>This is a functional component.</p>
    </div>
  );
}

export default Greeting;

This component is a simple greeting message that can be rendered anywhere in the application.

Functional components are easier to write, understand, and test. They are also recommended for most scenarios in React development. However, there are cases where class components are still useful, especially when working with complex state management or lifecycle methods.

```javascript
// React component example

import React from 'react';

function App() {
  return (
    <div>
      <h1>Welcome to AlgoDaily!</h1>
      <p>Learn and explore frontend development.</p>
    </div>
  );
}

export default App;

```

Introduction to React Components Multiple Choice

Which of the following is true about React components?

Creating Functional Components

Creating Functional Components

In React, functional components are created as JavaScript functions. They are a simpler and more concise way of defining components compared to class components.

Functional components are especially useful when you only need to render UI based on the given props and don't require any internal state or lifecycle methods.

Here's an example of a functional component:

function Greeting() {
  return (
    <div>
      <h2>Hello, World!</h2>
      <p>This is a functional component.</p>
    </div>
  );
}

In this example, the Greeting component simply renders a div element containing a heading and a paragraph. This component can be reused and rendered anywhere in your application.

With functional components, you can also utilize React hooks such as the useState hook to introduce state management into your components.

```javascript
// In React, functional components are created as JavaScript functions

function Greeting() {
  return (
    <div>
      <h2>Hello, World!</h2>
      <p>This is a functional component.</p>
    </div>
  );
}
```

Creating Functional Components Swipe

Creating functional components requires the use of class syntax.

Using Props to Pass Data

Using Props to Pass Data

One of the key concepts in React is props. Props (short for properties) allow you to pass data from a parent component to a child component.

Let's take a look at an example:

// Let's create a simple parent component

function ParentComponent() {
  const greeting = "Hello, World!";
  return (
    <div>
      <ChildComponent greeting={greeting} />
    </div>
  );
}

// Now let's create the child component

function ChildComponent(props) {
  return (
    <div>
      <h2>{props.greeting}</h2>
      <p>This is a child component.</p>
    </div>
  );
}

// In this example, the ParentComponent passes the greeting
// value as a prop called 'greeting' to the ChildComponent.

// The ChildComponent receives the prop and renders it in
// a heading element. The prop can be accessed using the 'props'
// parameter passed to the functional component.

// This way, data can be passed from the parent component to
// the child component using props.

In the code snippet above, we have a ParentComponent that renders a ChildComponent. The ParentComponent has a variable called greeting with the value "Hello, World!".

The greeting value is passed to the ChildComponent as a prop named greeting.

Inside the ChildComponent, the prop value is accessed using the props parameter passed to the function. The prop is then rendered inside a heading element.

By using the props, we can pass data from the parent component to the child component and utilize it to render dynamic content or perform other operations.

```javascript
// Let's create a simple parent component

function ParentComponent() {
  const greeting = "Hello, World!";
  return (
    <div>
      <ChildComponent greeting={greeting} />
    </div>
  );
}

// Now let's create the child component

function ChildComponent(props) {
  return (
    <div>
      <h2>{props.greeting}</h2>
      <p>This is a child component.</p>
    </div>
  );
}

// In this example, the ParentComponent passes the greeting
// value as a prop called 'greeting' to the ChildComponent.

// The ChildComponent receives the prop and renders it in
// a heading element. The prop can be accessed using the 'props'
// parameter passed to the functional component.

// This way, data can be passed from the parent component to
// the child component using props.

```

True or False

Props allow you to pass data from a parent component to a child component.

Rendering Components Conditionally

Rendering Components Conditionally

In React, you can render components conditionally based on certain conditions or states. This allows you to show different components or content depending on the current state of your application.

For example, let's say you have a simple application where a user can either be logged in or be a guest. You want to display a personalized greeting if the user is logged in, and a signup prompt if the user is a guest.

Here's an example of how you can conditionally render components based on the value of a prop:

function UserGreeting() {
  return (
    <div>
      <h1>Welcome back!</h1>
      <button onClick={logout}>Logout</button>
    </div>
  );
}

function GuestGreeting() {
  return (
    <div>
      <h1>Please sign up.</h1>
      <button onClick={login}>Login</button>
    </div>
  );
}

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;

  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  const login = () => {
    setIsLoggedIn(true);
  };

  const logout = () => {
    setIsLoggedIn(false);
  };

  return (
    <div>
      <Greeting isLoggedIn={isLoggedIn} />
    </div>
  );
}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

In this example, we have three components: UserGreeting, GuestGreeting, and Greeting.

  • UserGreeting component displays a welcome message and a button to logout.
  • GuestGreeting component displays a signup prompt and a button to login.
  • Greeting component checks the isLoggedIn prop and renders either the UserGreeting or GuestGreeting component accordingly.

The parent App component holds the isLoggedIn state and passes it to the Greeting component as a prop.

When the login button is clicked, the isLoggedIn state is set to true, and the UserGreeting component is rendered.

When the logout button is clicked, the isLoggedIn state is set to false, and the GuestGreeting component is rendered.

By rendering components conditionally, you can provide a personalized user experience based on the current state or conditions of your application.

```javascript
// Let's create a simple example

function UserGreeting() {
  return (
    <div>
      <h1>Welcome back!</h1>
      <button onClick={logout}>Logout</button>
    </div>
  );
}

function GuestGreeting() {
  return (
    <div>
      <h1>Please sign up.</h1>
      <button onClick={login}>Login</button>
    </div>
  );
}

// Create a component that determines whether
// to render UserGreeting or GuestGreeting based on
// the value of the isLoggedIn prop.

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;

  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

// Parent component that holds the isLoggedIn state
// and renders the Greeting component.

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  const login = () => {
    setIsLoggedIn(true);
  };

  const logout = () => {
    setIsLoggedIn(false);
  };

  return (
    <div>
      <Greeting isLoggedIn={isLoggedIn} />
    </div>
  );
}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
```

Rendering Components Conditionally Multiple Choice

What is a benefit of rendering components conditionally?

Handling Events in Components

Handling Events in Components

In React, you can handle user interactions and events by adding event handlers to your components. Event handlers are functions that are executed when a certain event occurs, such as a button click or a form submission.

Let's create a simple button component that triggers an event when clicked:

function Button(props) {
  const handleClick = () => {
    // Handle the click event here
    console.log('Button clicked!');
  };

  return (
    <button onClick={handleClick}>{props.label}</button>
  );
}

function App() {
  return (
    <div>
      <h1>Handling Events in Components</h1>
      <p>In React, you can handle user interactions and events by adding event handlers to your components. Let's create a simple button component that triggers an event when clicked.</p>
      <Button label="Click me!" />
    </div>
  );
}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

In this example, we have a Button component that takes a label prop. Inside the component, we define a function handleClick that gets executed when the button is clicked. The handleClick function simply logs a message to the console.

The button element has an onClick attribute that is assigned the handleClick function. This binds the function as the event handler for the button's click event.

When the button is clicked, the handleClick function is executed, and the message 'Button clicked!' is logged to the console.

You can modify the handleClick function to perform any desired action when the button is clicked, such as updating state, making API calls, or navigating to another page.

```javascript
// Let's create a simple button component that triggers an event when clicked

function Button(props) {
  const handleClick = () => {
    // Handle the click event here
    console.log('Button clicked!');
  };

  return (
    <button onClick={handleClick}>{props.label}</button>
  );
}

function App() {
  return (
    <div>
      <h1>Handling Events in Components</h1>
      <p>In React, you can handle user interactions and events by adding event handlers to your components. Let's create a simple button component that triggers an event when clicked.</p>
      <Button label="Click me!" />
    </div>
  );
}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
```

Handling Events in Components Multiple Choice

Which of the following is NOT a best practice for handling events in React components?

Stateful Components with useState Hook

Stateful Components with useState Hook

React provides the useState hook as a way to manage state in functional components. We can use the useState hook to create stateful components by defining a state variable and an update function.

The useState hook takes an initial state value as an argument and returns an array containing the current state value and a function to update the state value.

Here's an example of how to use the useState hook to create a simple counter component:

import React, { useState } from 'react';

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

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  return (
    <div>
      <h2>Counter</h2>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

function App() {
  return (
    <div>
      <h1>Stateful Components with useState Hook</h1>
      <p>React provides the useState hook as a way to manage state in functional components. We can use the useState hook to create stateful components by defining a state variable and an update function. Let's create a simple Counter component to demonstrate this:</p>
      <Counter />
    </div>
  );
}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

In this example, we define a Counter component that uses the useState hook to create a state variable count and an update function setCount. The initial state value is 0.

The Counter component renders the current value of count and two buttons to increment and decrement the count. The increment and decrement functions update the count state using the setCount function.

We can use the useState hook multiple times in a component to create multiple independent state variables.

The useState hook ensures that the component is re-rendered whenever the state value is updated.

Feel free to experiment with the code and see how the counter component renders and updates the count value on the screen.

```javascript
// Replace with stateful component code

import React, { useState } from 'react';

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

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  return (
    <div>
      <h2>Counter</h2>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

function App() {
  return (
    <div>
      <h1>Stateful Components with useState Hook</h1>
      <p>React provides the useState hook as a way to manage state in functional components. We can use the useState hook to create stateful components by defining a state variable and an update function. Let's create a simple Counter component to demonstrate this:</p>
      <Counter />
    </div>
  );
}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
```

True or False

React provides the useState hook as a way to manage state in functional components. We can use the useState hook to create stateful components by defining a state variable and an update function.

Lifting State Up

Lifting State Up

Lifting state up is a technique in React where the state management is moved from a child component to a parent component in order to share data between multiple child components.

To understand lifting state up, let's consider an example. Imagine we have a parent component called TemperatureConverter that consists of two child components: CelsiusInput and FahrenheitInput.

The CelsiusInput component takes a temperature in Celsius as an input, and the FahrenheitInput component takes a temperature in Fahrenheit as an input.

The goal is to allow the user to input a temperature in one component and automatically update the other component with the converted temperature.

To accomplish this, we need to lift the state of the temperatures from the child components to the parent component. The parent component will handle the conversion logic and update the state accordingly.

Here's an example of how we can implement this in React:

import React, { useState } from 'react';

function TemperatureConverter() {
  const [celsius, setCelsius] = useState(0);
  const [fahrenheit, setFahrenheit] = useState(0);

  const handleCelsiusChange = (event) => {
    const value = event.target.value;
    setCelsius(value);
    setFahrenheit((value * 9) / 5 + 32);
  };

  const handleFahrenheitChange = (event) => {
    const value = event.target.value;
    setFahrenheit(value);
    setCelsius(((value - 32) * 5) / 9);
  };

  return (
    <div>
      <h2>Lifting State Up</h2>
      <div>
        <label>Celsius:</label>
        <input type="number" value={celsius} onChange={handleCelsiusChange} />
      </div>
      <div>
         <label>Fahrenheit:</label>
         <input type="number" value={fahrenheit} onChange={handleFahrenheitChange} />
      </div>
    </div>
  );
}

export default TemperatureConverter;

In this example, the TemperatureConverter component holds the state for both the celsius and fahrenheit values using the useState hook. The component defines two event handlers, handleCelsiusChange and handleFahrenheitChange, to update the state based on user input.

The CelsiusInput and FahrenheitInput components receive the values as props and display them in their respective input fields. When the user changes the value in one input field, the corresponding event handler updates the state, which triggers a re-render of both input fields.

By lifting the state up to the TemperatureConverter component, we have centralized the state management and ensured that both child components always display the correct converted temperature value.

Lifting state up is useful in situations where multiple components need access to the same data or when you need to synchronize the state between components. It promotes reusability and makes the code easier to understand and maintain.

```javascript
// Lifting State Up

// Lifting state up is the process of moving the state
// management from a child component to a parent component
// in order to share the data between multiple child components.

// Let's say we have a parent component called `TemperatureConverter`
// that consists of two child components: `CelsiusInput`
// and `FahrenheitInput`.

// The `CelsiusInput` component takes a temperature in Celsius
// as an input and the `FahrenheitInput` component takes a temperature
// in Fahrenheit as an input.

// The goal is to allow the user to input a temperature in one input field
// and automatically update the other input field with the converted temperature.

// To achieve this, we need to lift the state of the temperatures
// from the child components to the parent component and have the parent
// component handle the conversion logic and update the state.

// Here's an example of how this can be implemented:

import React, { useState } from 'react';

function TemperatureConverter() {
  const [celsius, setCelsius] = useState(0);
  const [fahrenheit, setFahrenheit] = useState(0);

  const handleCelsiusChange = (event) => {
    const value = event.target.value;
    setCelsius(value);
    setFahrenheit((value * 9) / 5 + 32);
  };

  const handleFahrenheitChange = (event) => {
    const value = event.target.value;
    setFahrenheit(value);
    setCelsius(((value - 32) * 5) / 9);
  };

  return (
    <div>
      <h2>Lifting State Up</h2>
      <div>
        <label>Celsius:</label>
        <input type="number" value={celsius} onChange={handleCelsiusChange} />
      </div>
      <div>
         <label>Fahrenheit:</label>
         <input type="number" value={fahrenheit} onChange={handleFahrenheitChange} />
      </div>
    </div>
  );
}
```

True or False

Lifting state up is the technique of moving the state management from a parent component to a child component in order to share data between multiple child components.

Component Composition

Component Composition

In React, component composition refers to the technique of combining smaller components together to build larger and more complex components.

Think of component composition as a way of building a hierarchy of reusable building blocks. Each component represents a specific functionality or feature, and by composing them together, we can create powerful and flexible UIs.

Let's consider an example to better understand component composition. Suppose we want to build a basketball scoreboard component in React. The scoreboard component will display the scores of two teams: the Lakers and the Raptors.

To implement this, we can create smaller components for each team's score and then compose them inside a parent component called Scoreboard.

Here's an example implementation:

import React from 'react';

function Scoreboard() {
  return (
    <div>
      <h2>Scoreboard</h2>
      <TeamScore teamName="Lakers" score={98} />
      <TeamScore teamName="Raptors" score={102} />
    </div>
  );
}

function TeamScore({ teamName, score }) {
  return (
    <div>
      <h3>{teamName}</h3>
      <p>Score: {score}</p>
    </div>
  );
}

export default Scoreboard;

In this example, the Scoreboard component is the parent component that contains two instances of the TeamScore component. Each TeamScore component displays the team name and score.

By composing the TeamScore components inside the Scoreboard component, we can build a complete scoreboard UI that renders the scores of both teams.

This technique of component composition allows us to break down complex UIs into smaller and more manageable components. We can reuse these smaller components in multiple places of our application and easily update or modify them as needed.

Component composition is a powerful concept in React that promotes reusability and modular development. It enables us to build complex UIs by combining simple and independent building blocks.

```javascript
// Let's suppose we want to build a simple basketball scoreboard component in React.

import React from 'react';

function Scoreboard() {
  return (
    <div>
      <h2>Scoreboard</h2>
      <TeamScore teamName="Lakers" score={98} />
      <TeamScore teamName="Raptors" score={102} />
    </div>
  );
}

function TeamScore({ teamName, score }) {
  return (
    <div>
      <h3>{teamName}</h3>
      <p>Score: {score}</p>
    </div>
  );
}

export default Scoreboard;
```

Component Composition Multiple Choice

What is component composition?

Lifecycle Methods

Lifecycle Methods in React

Lifecycle methods are special methods that are automatically called by React at specific points during the life cycle of a component. These methods can be used to perform actions at different stages of the component's life cycle, such as when it is created, updated, or destroyed.

In class components, some common lifecycle methods include:

  • constructor(): This method is called when a component is first created. It is used to initialize the component's state and bind event handlers.

  • componentDidMount(): This method is called after the component has been rendered to the DOM. It is often used to fetch data from an API or set up event listeners.

  • componentDidUpdate(prevProps, prevState): This method is called after a component has been updated. It receives the previous props and state as arguments, allowing you to compare the current and previous values and perform any necessary actions.

  • componentWillUnmount(): This method is called just before a component is removed from the DOM. It is used to clean up any resources or event listeners created in the componentDidMount() method.

Here's an example of a class component with lifecycle methods:

import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  componentDidMount() {
    console.log('Component mounted');
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState.count !== this.state.count) {
      console.log('Count updated');
    }
  }

  componentWillUnmount() {
    console.log('Component unmounted');
  }

  incrementCount() {
    this.setState(prevState => ({ count: prevState.count + 1 }));
  }

  render() {
    return (
      <div>
        <h2>Counter: {this.state.count}</h2>
        <button onClick={() => this.incrementCount()}>Increment</button>
      </div>
    );
  }
}

export default Counter;
```javascript
// Replace with relevant code or explanation about lifecycle methods
// Make sure to provide examples and explanations specific to class components

import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  componentDidMount() {
    console.log('Component mounted');
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState.count !== this.state.count) {
      console.log('Count updated');
    }
  }

  componentWillUnmount() {
    console.log('Component unmounted');
  }

  incrementCount() {
    this.setState(prevState => ({ count: prevState.count + 1 }));
  }

  render() {
    return (
      <div>
        <h2>Counter: {this.state.count}</h2>
        <button onClick={() => this.incrementCount()}>Increment</button>
      </div>
    );
  }
}

export default Counter;
```

Lifecycle Methods Multiple Choice

Which lifecycle method is called after a component has been updated?

React Hooks

React Hooks

React Hooks are a new addition in React 16.8 that allow you to use state and other React features without using class components. Hooks are functions that let you 'hook into' React state and lifecycle features from function components.

One of the most commonly used hooks is the useState hook. It allows you to add state to your functional components. Let's take a look at an example:

import React, { useState } from 'react';

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

  function increment() {
    setCount(prevCount => prevCount + 1);
  }

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

export default Counter;

In this example, we're using the useState hook to add a state variable count and a function setCount that allows us to update the value of count. The initial value of count is set to 0.

Whenever the button is clicked, the increment function is called which updates the value of count by incrementing it by 1. The updated value is then displayed in the h2 tag.

React Hooks allow you to easily manage state and perform side effects in functional components, making them a powerful tool for building React applications.

By using hooks, you can write more concise and readable code compared to class components, as you no longer need to deal with the complexities of the this keyword and lifecycle methods.

```javascript
// React Hooks Example

import React, { useState } from 'react';

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

  function increment() {
    setCount(prevCount => prevCount + 1);
  }

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

export default Counter;

```

React Hooks Swipe

React Hooks allow you to add state and other React features to function components without using class components.

Generating Complete

Generating complete for this lesson!

Open interactive view →