Nella lezione precedente abbiamo visto come è possibile introdurre diverse viste all'interno della nostra applicazione e alternarle l'una all'altra selezionandole tramite l'URL a loro associato.
Vedremo ora come è possibile estendere il codice dell'esempio aggiungendo un tradizionale menu di navigazione, ovvero dando la possibilità all'utente di poter accedere alla vista desiderata selezionando la voce relativa all'interno del menu, senza doverne digitare manualmente il nome nell'URL.
Il componente Link
Per dare corpo al nostro menu di navigazione, dobbiamo creare tanti collegamenti (link) quante sono le viste che vogliamo rendere accessibili.
Non faremo ricorso al tradizionale elemento <a>
del linguaggio HTML, bensì adotteremo un componente React apposito che ci consente di mostrare un link all'interno della pagina associandolo al percorso che riconduce alla vista da visualizzare: il componente Link.
Questo componente fa sempre parte del package react-router-dom, che abbiamo installato nella lezione precedente allo scopo di definire i percorsi delle viste tramite il componente Route, inserendolo all'interno del contenitore BrowserRoute.
All'interno del medesimo BrowserRoute possiamo aggiungere il componente Link per visualizzare il collegamento che ci porta a una vista. Ad esempio, possiamo modificare il file App.js in questo modo:
import React, { Component } from "react";
import { BrowserRouter, Route, Link } from "react-router-dom";
import logo from "./logo.svg";
import "./App.css";
import AppDescription from "./components/AppDescription.js";
import HomeView from "./components/HomeView.js";
import AboutView from "./components/AboutView.js";
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React!</h1>
</header>
<AppDescription text="Benvenuto nella mia prima applicazione React!" />
<BrowserRouter>
<div>
<Link to="/">Home</Link>
<Link to="/about">Informazioni</Link>
<Route exact path="/" component={HomeView} />
<Route exact path="/about" component={AboutView} />
</div>
</BrowserRouter>
</div>
);
}
}
export default App;
Poniamo ora l'attenzione alle parti del file che sono state modificate. Innanzitutto, abbiamo aggiunto Link all'istruzione che importa i componenti dal package react-router-dom, analogamente a quanto già fatto per BrowserRouter e Route:
import { BrowserRouter, Route, Link } from "react-router-dom";
Successivamente, abbiamo inserito il componente Link all'interno del BrowserRouter specificando il percorso della vista nell'attributo to e inserendo il testo da visualizzare per il link come contenuto dell'elemento:
<BrowserRouter>
<div>
<Link to="/">Home</Link>
<Link to="/about">Informazioni</Link>
<Route exact path="/" component={HomeView} />
<Route exact path="/about" component={AboutView} />
</div>
</BrowserRouter>
Se la pagina è già visualizzata all'interno del browser, è probabile che si aggiorni automaticamente se la compilazione va a buon fine; qualora ciò non avvenisse, è sufficiente premere F5 nel browser oppure eseguire nuovamente il comando npm start dal prompt dei comandi.
Se tutto è andato come previsto, nella pagina appariranno i link che consentono di navigare tramite click nelle viste corrispondenti ai percorsi associati.
Ora abbiamo un menu di navigazione, certo, ma salterà subito all'occhio quanto sia rudimentale e soprattutto formattato male; ad esempio, non è presente nemmeno uno spazio tra i link del menu, poiché il ritorno a capo che separa le due istanze del componente Link non è significativo per la sintassi JSX.
Vediamo come ottimizzare il nostro menu e come migliorarlo per renderlo più funzionale.
Creare un componente NavBar
Per evitare un eccessivo cluttering del componente principale dell'applicazione, è consigliabile isolare il menu di navigazione e inserirlo all'interno di un componente React a sé stante.
Creiamo quindi un nuovo file nella cartella components con un nome significativo, NavBar.js, e spostiamo al suo interno il necessario:
import React, { Component } from "react";
import { Link } from "react-router-dom";
class NavBar extends Component {
render() {
return <div>
<Link to="/">Home</Link>
<Link to="/about">Informazioni</Link>
</div>
}
}
export default NavBar;
Possiamo snellire il file App.js sostituendo i link con una istanza del nuovo componente NavBar, ricordandoci sempre di importare il tipo corrispondente.
Qui di seguito le parti salienti del file sottoposto a modifiche:
import { BrowserRouter, Route } from "react-router-dom";
...
import NavBar from "./components/NavBar";
...
<BrowserRouter>
<div>
<NavBar />
<Route exact path="/" component={HomeView} />
<Route exact path="/about" component={AboutView} />
</div>
</BrowserRouter>
...
In questo modo possiamo lavorare in modo mirato sul menu modificando il file NavBar.js senza intaccare il resto dei file e del codice.
Creare un separatore
Vediamo ora come risolvere il problema della separazione delle voci del menu. La soluzione ideale sarebbe quella di creare un nuovo componente dedicato a questo scopo, da inserire tra ciascuna coppia di link consecutivi, inserendo semplicemente un paio di spazi e un carattere apposito, come un trattino o un punto.
Vi sono due considerazioni da fare in proposito: il markup da inserire è talmente semplice che difficilmente giustifica la creazione di un file dedicato da destinare a un nuovo componente; inoltre, il suo utilizzo è al momento limitato al menu di navigazione, quindi potremmo inserirlo direttamente all'interno del file NavBar.js senza complicare inutilmente la struttura generale del progetto ed evitando di esporlo all'esterno.
Oltre a ereditare dalla classe Component, grazie a React possiamo creare un componente definendo solamente una semplicissima funzione di rendering.
Modifichiamo quindi il file NavBar.js aggiungendo la definizione del nostro separatore in questo modo:
const Separator = () => <span> · </span>;
Abbiamo così definito una funzione lambda che, se invocata, restituisce un elemento <span> con un puntino circondato da spazi: questo sarà il componente che potremo utilizzare nel menu di navigazione inserendone una istanza tra una voce e l'altra.
class NavBar extends Component {
render() {
return <div>
<Link to="/">Home</Link>
<Separator />
<Link to="/about">Informazioni</Link>
</div>
}
}
L'uso di funzioni pure è una delle modalità consentite da React per creare componenti estremamente semplici. Se occorre, è possibile scrivere la funzione affinché accetti parametri dall'esterno, ad esempio per passare valori da riportare all'interno del markup. Se è necessario costruire componenti più complessi per i quali è necessario gestire uno stato e le sue possibili variazioni, allora non possiamo accontentarci della funzione ma dobbiamo estendere la classe Component così come abbiamo fatto fino a ora.
Il nostro menu di navigazione viene ora visualizzato correttamente, pur rimanendo molto semplice e spartano. Nulla vieta tuttavia di ricercare e installare package esterni che contengano fogli di stile con classi già pronte all'uso - come il noto Bootstrap, ad esempio - per creare il markup di menu più complessi e articolati.
Nella prossima lezione vedremo come inserire nuove viste ed estendere la configurazione del routing per avvicinare il nostro esempio a un'applicazione reale e funzionante, seppure dimostrativa.