Les composants
Notre page comporte 2 composants React :
function HomePage() {
const {accomodations, loading} = useAccomodations()
return (<Layout loading={loading}>
{accomodations.map(accomodation => <Accomodation
accomodation={accomodation}
onBook={() => action()}
>)}
</Layout>)
}
Nous avons séparé la logique d'animation dans une fonction useAccomodations
.
Ainsi, nos composants sont centrés sur 1 seule reponsabilité : l'affichage.
Rôles de nos 2 composants
Le principe de React est la composition. On imbrique des composants dans une structure déclarative pour représenter l'interface graphique attendue.
Le rôle de notre composant Layout
est de s'occuper de la disposition générale des éléments de la page.
Et celui de notre composant Accomodation
est d'afficher la carte d'un logement de vacances que l'utilisateur peut réserver.
L'échéance de votre démo approche. Et vous n'avez pas le temps de peaufiner le rendu graphique. Alors prenons un raccourci, qui fait désormais le quotidien de tous les développeurs.
Un raccourci
Utilisons ChatGPT pour créer ces 2 composants React.
Voici le prompt :
Ecris le code des composants React Layout et Accomodation pour ma web application de réservation de logements de vacances :
function HomePage() {
const {accomodations, loading} = useAccomodations()
return (<Layout loading={loading}>
{accomodations.map(accomodation => <Accomodation
accomodation={accomodation}
onBook={() => action()}
>)}
</Layout>)
}
Le résultat est minimaliste. Et surtout pas très beau.
Alors améliorons cela en ajoutant un screenshot d'un site bien connu :
Améliore les composants pour que ça ressemble à ça
.
Et là, nous avons bien mieux !
Le Layout
possède un bandeau de recherche, qui va nous être utile.
import React from 'react';
import './Layout.css';
function Layout({ children, loading }) {
return (
<div className="layout">
<header className="header">
<div className="search-bar">
<input type="text" placeholder="Rechercher une destination" />
<input type="text" placeholder="Arrivée" />
<input type="text" placeholder="Départ" />
<input type="text" placeholder="Ajouter des voyageurs" />
<button className="search-button">🔍</button>
</div>
</header>
<main className="main-content">
{loading ? (
<div className="loading">Loading...</div>
) : (
<div className="accommodations-list">{children}</div>
)}
</main>
</div>
);
}
export { Layout };
Et le composant Accomodation
comporte notre bouton de réservation.
import React from 'react';
import './Accomodation.css';
function Accomodation({ accomodation, onBook }) {
return (
<div className="accomodation-card">
<img src={accomodation.imageUrl} alt={accomodation.name} className="accomodation-image" />
<div className="accomodation-details">
<div className="accomodation-header">
<h2>{accomodation.location}</h2>
<button className="favorite-button">❤️</button>
</div>
<p className="accomodation-name">{accomodation.name}</p>
<p className="accomodation-dates">{accomodation.dates}</p>
<p className="accomodation-host">{accomodation.host}</p>
<p className="accomodation-price">{accomodation.price} € par nuit</p>
<button className="book-button" onClick={onBook}>Réserver</button>
</div>
</div>
);
}
export { Accomodation };
Utilisons ces 2 composants pour voir ce que ça donne.
Notre repository de test
Il reste un problème pour notre démo : nous n'avons pas de listing de logements à louer.
Rappelons-nous de notre dépendance MemoryBookingRepository
:
export class MemoryBookingRepository {
_bookings = [];
_accomodations = [{ id: "accomodation-1" }, { id: "accomodation-2" }];
...
}
Il ne comporte que les 2 identifiants des logements, car nous n'avions besoin de rien de plus.
Etoffons un peu cela avec un fichier fakeAccomodations.js
export const fakeAccomodations = [
{id: "accomodation-1", name: "Villa 6 pièces en Provence", imageUrl: "https://picsum.photos/200/300", location: "Saint-Rémi", host: "John Holydays", price: 230 },
{id: "accomodation-2", name: "Villa 6 pièces en Provence", imageUrl: "https://picsum.photos/200/300", location: "Saint-Rémi", host: "John Holydays", price: 230 },
{id: "accomodation-3", name: "Villa 6 pièces en Provence", imageUrl: "https://picsum.photos/200/300", location: "Saint-Rémi", host: "John Holydays", price: 230 },
{id: "accomodation-4", name: "Villa 6 pièces en Provence", imageUrl: "https://picsum.photos/200/300", location: "Saint-Rémi", host: "John Holydays", price: 230 },
{id: "accomodation-5", name: "Villa 6 pièces en Provence", imageUrl: "https://picsum.photos/200/300", location: "Saint-Rémi", host: "John Holydays", price: 230 },
{id: "accomodation-6", name: "Villa 6 pièces en Provence", imageUrl: "https://picsum.photos/200/300", location: "Saint-Rémi", host: "John Holydays", price: 230 },
]
Et injectons cela dans notre repository de test :
export class MemoryBookingRepository {
_bookings = [];
_accomodations = fakeAccomodations;
...
}
Il nous faut aussi ajouter une fonction à notre repository pour récupérer la liste des logements.
export class MemoryBookingRepository {
_bookings = [];
_accomodations = fakeAccomodations;
...
async getAccomodations() { return this._accomodations};
}
L'aperçu de notre première page
Et le résultat n'est pas si mal !
Le code complet de cette étape est disponible ici (opens in a new tab).