L'obiettivo di questa guida è creare una single page application React che rende a video gli ultimi 10 post di un sito WordPress.
L'applicazione sarà composta da tre componenti React:
- un componente
Blog
che ha lo scopo di creare la struttura del blog; - un componente
PostItem
, importato dal componenteblog
con lo scopo di generare le anteprime dei singoli post; - un componente
Post
, con lo scopo di renderizzare a video il contenuto dei singoli post.
La scelta del layout è arbitraria e il lettore potrà modificare il codice CSS secondo le sue preferenze. Per questa guida abbiamo deciso di creare un blog a scorrimento orizzontale in cui ogni anteprima di post occupa l'intera porzione disponibile dello schermo. Scorrendo lo schermo verso destra, si passa all'articolo successivo. Verso sinistra si torna al precedente.
Apriamo il progetto in un editor di codice (in questi esempi utilizzeremo Visual Studio Code).
Prima di iniziare, creiamo una directory components
all'interno della directory src
. Nella directory components
creiamo un file Blog.js
e un file PostItem
, che per il momento lasceremo vuoti.
Nel file App.js
rimuoviamo il codice presente e aggiungiamo il seguente:
import Blog from "./components/Blog";
import './App.css';
export default function App() {
return (
<div className="container">
<Blog />
</div>
);
}
Lo script inizia con due dichiarazioni import
. La prima importa il componente Blog
dallo script che abbiamo appena creato. La seconda dichiarazione import
importa il foglio di stile che si trova nella directory src
.
Ci limitiamo, poi, ad esportare il codice generato dalla funzione App
. Questo è composto dalla div#container
e dall'elemento Blog
in essa contenuto.
Gli hook
Apriamo, quindi, il file Blog.js
e importiamo le seguenti risorse:
import { useEffect, useState } from "react";
import axios from "axios";
import PostItem from "./PostItem";
useEffect
è un hook di React che permette di sincronizzare un componente con un sistema esterno. In pratica permette di recuperare i dati dopo che il componente è stato reso a video, non impattando sulle prestazioni dell'applicazione. I casi d'uso più frequenti possono riguardare il recupero di dati da un'origine esterna, l'aggiornamento diretto del DOM e i timer.
useEffect
va prima importato da react
, quindi utilizzato nella parte iniziale della funzione del componente. L'hook accetta due argomenti: una funzione e un array di dipendenze:
useEffect(() => {}, []);
useEffect
viene eseguito ad ogni render. Per evitare di finire in un loop, è sempre necessario passare alla funzione l'array delle dipendenze, anche se vuoto.
useState
è un hook di React che consente di aggiungere una variabile di stato ai componenti funzionali. Lo stato è definito come "la memoria di un componente" e viene in aiuto quando in un'applicazione è necessario tracciare dati o proprietà. Per utilizzare useState
è necessario importarlo da react
e quindi collocarlo all'inizio del componente in questo modo:
const [something, setSomething] = useState(val);
Dove:
something
è lo stato corrente della variabile di stato, inizialmente impostata suval
;setSomething
è una funzione che consente di modificare il valore assegnato in risposta a un'interazione.
La sintassi utilizzata è la sintassi di assegnazione per destrutturazione. Per aggiornare lo stato del componente, basterà quindi invocare la funzione setSomething
passandole il nuovo valore.
Importazione di axios
Subito dopo l'importazione degli hook useEffect
e useState
, importiamo axios
:
import axios from "axios";
Nella documentazione ufficiale, Axios è definito in questo modo:
Axios è un client HTTP basato su promesse per node.js e il browser. È isomorfo (= può essere eseguito nel browser e in nodejs con la stessa codebase). Lato server utilizza il modulo http nativo di node.js, mentre sul client (browser) utilizza XMLHttpRequests.
Ora che sappiamo a cosa servono le risorse importate, possiamo stabilire l'origine dei dati. Nei nostri esempi, importeremo gli ultimi 10 articoli del WordPress Developer Blog:
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';
Dalla lettura dei capitoli precedenti, dovrebbe ora essere chiaro che con questo URL chiediamo all'API le seguenti risorse:
id
: identificativo del post;slug
: slug del post;date
: data di pubblicazione;title
: titolo del post;excerpt
: riassunto;content
: contenuto;link
: link del post;_links
: link alle risorse collegate;_embed=author,wp:featuredmedia
: risorse incorporate.
La funzione del componente
Definiamo ora la funzione del componente:
export default function Blog() {
const [posts, setPosts] = useState([]);
useEffect(() => {
axios
.get(url)
.then(res => {
// vedi risposta nella console del browser
console.log(res.data);
// aggiorna il valore della variabile di stato posts
// con i dati ottenuti dall'API
setPosts(res.data);
})
.catch(error => console.log(error));
}, []);
return (
<div className="blog">
{posts.map(item => (
<PostItem
key={item.id}
post={item}
/>
))}
</div>
);
}
Per prima cosa, definiamo la variabile di stato posts
. Poi invochiamo l'hook useEffect
con lo scopo di accedere ai dati dell'API senza interferire con il rendering del componente. Per evitare un loop infinito, passiamo all'hook anche il secondo argomento, che in questo caso è un array vuoto.
Passiamo poi ad axios
. Il metodo get
effettua una richiesta GET all'API di WordPress. In questo caso, la risorsa passata è l'URI della Rest API che abbiamo definito in precedenza.
Il metodo then
esegue una funzione in caso di risposta positiva, mentre catch
esegue una diversa funzione in caso di errore.
Salviamo il file e spostiamoci nella console del browser. Dato che abbiamo inserito un console.log
nella funzione eseguita in caso di successo, la console dovrebbe mostrare un oggetto JSON degli ultimi post pubblicati sul sito Developer.wordpress.org/news/.
In caso qualcosa non vada a buon fine, vedremo nella console un messaggio di errore di Axios.
Infine, la funzione restituisce il codice da rendere a video:
return (
<div className="blog">
{posts.map(item => (
<PostItem
key={item.id}
post={item}
/>
))}
</div>
);
Il metodo map
itera tra gli elementi dell'oggetto posts
assegnando le proprietà key
e post
ad ogni nuova istanza dell'elemento PostItem
. Quest'ultimo genera le anteprime di ognuno dei post restituiti dall'API, come vedremo nella prossima lezione.
Il file Blog.js
Ecco il codice del file Blog.js
completo:
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>
);
}
Il componente Blog
è completo. Nella prossima lezione creeremo il componente PostItem
, che avrà il compito di generare le anteprime dei post.