Skip to main content

Communication between components and routing

Communication between components

Communication between components is important to build complex applications. In React, communication between components can be done by passing properties from a parent to a child component, or by using a callback function to pass data from the child to the parent.

Components can pass data to child components through properties, and these can be modified according to the child component's needs. Thus, any changes to the properties in the parent component will be automatically reflected in the child component.

Here is an example of using this mode of communication:

import React from 'react';

type ChildProps = {
data: {
lastName: string,
firstName: string
}
}

function Parent() {
const data = { lastName: 'Popescu', firstName: 'Ion' };

return (
<div>
<h1>Welcome, {data.lastName} {data.firstName}!</h1>
<Child data={data} />
</div>
);
}

function Child(props: ChildProps) {
const { lastName, firstName } = props.data;

return <div>
<p>LastName: {lastName}</p>
<p>FirstName: {firstName}</p>
</div>
}
note

In this example, the parent component (Parent) defines a data object with information about the current user. This object is passed to the child component (Child) as the data property. The child component receives this property and displays the information in p elements.

To communicate from a child component to a parent component in React.js, a callback function can be used. This method consists of defining a function in the parent component, which we then pass to the child component as a property. The child component can call the function when it needs to pass information back to the parent component.

Here is an example of using this method:

import React, { useState } from 'react';

function Parent() {
const [message, setMessage] = useState('');

// We define a function that receives a message
// and sets it as the state in the parent component
const handleMessageExchanged = (newMessage) => {
setMessage(newMessage);
}

return (
<div>
<p>Mesajul primit: {mesaj}</p>
<Child onMessageExchanged={handleMessageExchanged} />
</div>
);
}

function Child(props) {
const [message, setMessage] = useState('');

// Function that calls the parent's function to send the message
// from child back to parent
const handleClick = () => {
props.onMessageExchanged(message);
}

return (
<div>
<input type="text" value={message} onChange={(event) => setMesaj(event.target.value)} />
<button onClick={handleClick}>Send message</button>
</div>
);
}
note

In this example, the parent component defines a handleMessageExchanged function that receives a message and sets it as state in the parent component. This function is then passed to the child component as the onMessageExchanged property. The child component defines a handleClick function that calls the parent function with the message entered in the text field. When the user presses the "Send message" button, the message is sent back to the parent component and displayed in its p element.

This method is useful in situations where child components need to pass data to parent components.

Routing in React

What is routing and how does it work in React?

Routing is the process of managing navigation between different pages or sections of a web application. In React, routing is handled through a library called React Router. React Router provides a simple mechanism for defining routes in the application and displaying the components corresponding to those routes.

In React, routing is defined as an association between a URL and a component.

To manage routes in React, the React Router library must first be installed using a package manager such as npm:

npm install react-router-dom

Using React Router

After React Router has been installed, routes can be defined in the application.

import { BrowserRouter, Route, Route, Link } from 'react-router-dom';
import HomePage from './HomePage';
import AboutUsPage from './PaginaDespre';
import ContactPage from './ContactPage';

function App() {
return (
<BrowserRouter>
<div>
<nav>
<ul>
<li>
<Link to="/">Home page</Link>
</li>
<li>
<Link to="/despre">About us</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutUsPage />} />
<Route path="/contact" element={<ContactPage />} />
</Routes>
</div>
</BrowserRouter>
);
}
note

In this example, we have defined three different routes, each associated with a component. The first path, defined with exact path="/", is associated with the HomePage component and will be displayed when the user navigates to the application's root URL. The second route, defined with path="/about", is associated with the AboutUsPage component and will be displayed when the user navigates to the "/about" URL. The third route, defined with path="/contact", is associated with the ContactPage component and will be displayed when the user navigates to the "/contact" URL.

Another powerful feature of React Router is the ability to use parameters in routes. This can be useful, for example, to display the details of a particular item in a list.

import { BrowserRouter, Route, Route, Link } from 'react-router-dom';
import HomePage from './HomePage';
import ProductListPage from './ProductListPage';
import ProductDetailsPage from './ProductDetailsPage';

function App() {
return (
<BrowserRouter>
<div>
<nav>
<ul>
<li>
<Link to="/">Home page</Link>
</li>
<li>
<Link to="/products">Products</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/products" element={<ProductListPage />} />
<Route path="/products/:id" element={<ProductDetailsPage />} />
</Routes>
</div>
</BrowserRouter>
);
}
note

In the example above, the path /products/:id includes an id parameter that can be used to display the details of the product with the specified identifier. This parameter can be accessed in the ProductDetailsPage component using the useMatch hook in React Router.

const match = useMatch("/products/:id");
const productId = match?.params.id;