Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

I componenti Blog e PostItem

Definiamo i componenti Blog e PostItem della nostra applicazione per creare un sito WordPress headless con React
Definiamo i componenti Blog e PostItem della nostra applicazione per creare un sito WordPress headless con React
Link copiato negli appunti

Nel capitolo precedente, abbiamo visto come utilizzare gli elementi BrowserRouter, Routes e Route forniti dai corrispondenti componenti della libreria React Route.

Abbiamo visto come definire le route che associano i componenti Blog e Post ai corrispondenti URL tramite gli attributi path e element degli elementi Route.

Il file Blog.js

La prima route associa la pagina iniziale dell'app (path="/") al componente Blog. Non dovremo modificare nulla nel file Blog.js e per questo ci limitiamo a riportarne il codice:

import { useEffect, useState } from "react";
import axios from "axios";
import PostItem from "./PostItem";
const url = 'https://developer.wordpress.org/news/wp-json/wp/v2/posts?_fields=id,slug,date,title,excerpt,content,link,_links&_embed=author,wp:featuredmedia';
export default function Blog() {
	const [posts, setPosts] = useState([]);
	useEffect(() => {
		axios
		.get(url)
		.then(res => {
			console.log(res.data);
			setPosts(res.data);
		})
		.catch(error => console.log(error));
	}, []);
	return (
		<div className="blog">
			{posts.map(item => (
				<PostItem
					key={item.id}
					post={item}
				/>
			))}
		</div>
	);
}

Saranno invece necessarie alcune piccole modifiche al file PostItem.js. Qui dovremo sostituire l'elemento <a> che punta alla risorsa originaria con un elemento <Link>.

La documentazione di React Router definisce un <Link> come un elemento che permette all'utente di navigare ad un'altra pagina con un clic. In react-router-dom, un <Link> rende accessibile un elemento <a> con un attributo href che punta ad una data risorsa. Questo significa che operazioni come un clic destro potrebbero non avere l'effetto atteso.

Inoltre,

Un valore <Link to> relativo (che non inizia con /) si risolve rispetto alla route principale, il che significa che si basa sul percorso dell'URL a cui corrispondeva la route che ha reso quel <Link>. Può contenere .. per collegarsi a percorsi più in alto nella gerarchia. In questi casi, .. funziona esattamente come la funzione cd della riga di comando; ogni .. rimuove un segmento del percorso principale.

Un <Link> può avere anche una proprietà state, che può essere utilizzata per impostare un valore con stato per la nuova posizione che viene archiviato nello stato della cronologia. Sarà quindi possibile accedere a questo valore tramite useLocation().

Il file PostItem.js

Chiarito questo, apriamo il file PostItem.js e importiamo il componente Link da react-router-dom:

import { Link } from 'react-router-dom';

Passiamo al listato JSX e sostituiamo l'elemento <a> con <Link>:

<h2 className="post-title">
	<Link to={`/post/${post.slug}`} state={ { post: { item } } }>
		<p dangerouslySetInnerHTML={{ __html: post.title.rendered }} />
	</Link>
</h2>

Il valore assegnato all'attributo to stabilisce la risorsa di destinazione. Il valore di ${post.slug} viene generato dinamicamente in base al post corrente e permetterà di generare un URL specifico per ogni post restituito dalla Rest API.

L'output di un elemento Link

L'output di un elemento Link

Torniamo per un attimo allo script App.js e analizziamo il codice dell'elemento <Route> che fa riferimento al componente Post:

<Route
	path='/post/:slug'
	element={<Post />}
/>

Ora dovrebbe essere chiaro che il percorso associato al componente Post si compone di una parte dinamica che genera lo slug del post corrente. Quando l'utente, dalla pagina del blog, farà clic su un link, verrà reso a video il post corrispondente allo slug.

L'immagine che segue mostra l'output di un'anteprima di post generata dal componente PostItem.js.

L'anteprima del post generata da PostItem

L'anteprima del post generata da PostItem

L'immagine che segue mostra invece il codice HTML generato dal componente.

Il codice HTML generato da PostItem

Il codice HTML generato da PostItem

Ed ecco il codice completo del file PostItem.js:

import { useEffect, useState } from "react";
import { Link } from 'react-router-dom';
import axios from "axios";
export default function PostItem( { post } ){
	const [featuredImage, setFeaturedImage] = useState('https://images.pexels.com/photos/270404/pexels-photo-270404.jpeg');
	const [item, setItem] = useState(post);
	const [isLoading, setIsLoading] = useState(true);
	const date = new Date(post.date).toLocaleDateString("it-IT", {
		year: "numeric",
		month: "long",
		day: "numeric",
	});
	useEffect(() => {
		axios
		.get(post?._links?.["wp:featuredmedia"]?.[0]?.href)
		.then(res => {
			if(typeof res.data.source_url === "string"){
				setFeaturedImage(res.data.source_url);
			}
		})
		.catch(error => console.log(error))
		.finally(() => setIsLoading(false))
	}, []);
	return(
		<div className="post-container">
			<div className="post-content" id={post.slug}>
				<div className="post-featured-image">
					{
						isLoading ? <p>Loading...</p> : <img src={featuredImage} />
					}
				</div>
				<div className="post-details">
					<div className="post-date">
						{date}
					</div>
					<h2 className="post-title">
						<Link to={`/post/${post.slug}`} state={ { post: { item } } }>
							<p dangerouslySetInnerHTML={{ __html: post.title.rendered }} />
						</Link>
					</h2>
					<div
						className="post-excerpt"
						dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }}
					/>
				</div>
			</div>
		</div>
	);
}

Nella prossima lezione, creeremo l'ultimo componente della nostra app: il componente Post, responsabile del rendering di un oggetto post.

Ti consigliamo anche