React: how components communicate

React: how components communicate

In this article, we will explore the different ways of communicating between components in React and how to effectively use the mechanisms provided by the library.

React is a widely used JavaScript library for building dynamic and reusable user interfaces. When developing complex applications in React, it is common to have to manage communication between different components. In this article, we will explore the different ways of communicating between components in React and how to effectively use the mechanisms provided by the library.

Props: the foundation of one-way communication

Communication between components in React is based on the principle of "one-way communication". In this mode, data is passed from a parent component to one or more child components through props. Props are essentially attributes that a component receives from its parent component.

Example of passing props from a parent component to a child component:


// Parent Component
import React from 'react';
import ChildComponent from './ChildComponent';

const ParentComponent = () => {
   const data = "Data to pass to child component";

   return (
     <ChildComponent data={data} />
   );
};

// Child component
import React from 'react';

const ChildComponent = (props) => {
   return (
     <div>{props.data}</div>
   );
};

Props allow for clear, one-way communication, but can become restrictive when it is necessary to share data between components that do not have a direct parent-child relationship.

Advanced solutions with states and callbacks

To overcome the limitations of props, React offers state management. A state can be defined within a component and modified via the setState function. Communication between components can occur through the modification of a state that is passed as a prop.

Example of communication through state:


// Parent Component
import React, { useState } from 'react';
import ChildComponent from './ChildComponent';

const ParentComponent = () => {
   const [data, setData] = useState("Data to pass to child component");

   const handleDataChange = newData => {
     setData(newData);
   };

   return (
     <div>
       <ChildComponent data={data} onDataChange={handleDataChange} />
     </div>
   );
};

// Child component
import React from 'react';

const ChildComponent = (props) => {
   const handleChange = () => {
     const newData = "New data from child component";
     props.onDataChange(newData);
   };

   return (
    <div>
       <div>{props.data}</div>
       <button onClick={handleChange}>Change Data</button>
     </div>
   );
};

Using this approach, the child component can communicate with the parent through a callback function passed as a prop.

Context API: for long-range communication

As an application grows in complexity, it can become inefficient to pass data through numerous layers of components. In these cases, React's Context API can be an effective solution. The Context API allows you to share global data between components without having to manually pass props through each layer.


// Creation of the Context
import { createContext, useContext, useState } from 'react';

const DataContext = createContext();

// Provider component
const DataProvider = ({ children }) => {
   const [data, setData] = useState("Data shared across context");

   return (
     <DataContext.Provider value={{ data, setData }}>
       {children}
     </DataContext.Provider>
   );
};

// Hook useContext into a child component
const ChildComponent = () => {
   const { data, setData } = useContext(DataContext);

   const handleChange = () => {
     const newData = "New data from child component";
     setData(newData);
   };

   return (
     <div>
       <div>{data}</div>
       <button onClick={handleChange}>Change Data</button>
     </div>
   );
};

Redux: global state management

When dealing with complex applications with a large amount of shared data, Redux is a popular library for managing global state. Redux introduces a global "store" that contains application state. Components can access and change the state of the store using actions.

The Redux implementation requires defining a store, actions, and reducers. It is a more advanced solution suitable for large projects.

Conclusion

Communication between components in React is essential for building robust and scalable applications. The choice of communication method depends on the specific needs of the project. Props are ideal for one-way communication, state and callbacks offer flexibility, the Context API is useful for long-range communication, while Redux is a complete solution for managing global state. The choice will depend on the specific needs of the project and its complexity.