È possibile memorizzare un elemento di React in una variabile:
Questo elemento però è fisso, è poco più di un semplice blocco di HTML.
La potenza di React si scatena con i componenti, che a differenza degli elementi possono essere configurati a piacere.
Immaginiamo un componente card al quale possiamo passare la foto, il titolo, ecc. come a una funzione. E infatti uno dei modo per creare i componenti è quello mediante funzioni:
Questo esempio inizialmente non funzionerà: utilizza la console del browser per risolvere i vari errori. Il problema più frequente sarà la presenza di elementi non autoconclusi: ad esempio dovrai usare <input /> e non <input>.
Nota l'iniziale maiuscola nel nome della funzione.
Nota come è stato richiamato nel metodo render.
Nota: avremmo potuto richiamarlo con Navbar() come una normale funzione, ma così è molto più semplice inserirlo nell'HTML.
Stilizzare i componenti
Per applicare gli stili ai componenti si usa l'attributo className, al posto di class:
Si procede poi creando gli stili come di consueto, nel file .css
Inoltre per usare l'attributo style devi fare in questo modo:
nota: di fatto stai passando un oggetto JavaScript con una proprietà width.
Componenti nidificati
Volendo passare a render più componenti bisogna inserirli in un div che li contenga: questo "nodo" andrà ad innestarsi nell'elemento #root del DOM (Modello a Oggetti del Documento)
Tag a chiusura automatica
Normalmente i tag HTML sono in coppie di apertura e chiusura, del tipo:
ma ci sono alcuni tag, come ad es. <input>, che non hanno bisogno di un tag di chiusura.
Per utilizzarli in JSX senza riceve un errore bisogna utilizzare il simbolo / che indica che il tag si chiude in sè stesso, come nell'esempio:
Componenti in file separati
Per tenere in ordine il codice, è buona norma creare un file separato per ogni componente o gruppo di componenti affini, importandoli poi con dei tag script:
Ricorda che i file vengono letti in ordine, quindi se index.js usa un componente presente in Navbar.js, mettere gli script in questo modo non funzionerebbe, perché quando index.js viene eseguito non sa ancora che cosa sia il componente Navbar:
Passare le proprietà a un componente
In questo esempio vediamo una pagina che usa la griglia di Bootstrap per visualizzare tre Card, passando a ognuna un diverso attributo titolo:
Il componente che disegna la card è questo. Gli attributi vengono passati nell'oggetto props, che è possibile utilizzare per mostrare una specifica proprietà, come ad esempio props.titolo:
Nota: quando in JSX vogliamo scrivere un blocco di JavaScript puro, lo mettiamo tra parentesi graffe, come ad esempio in { props.titolo }.
Ecco come comporre il percorso di un file per passarlo come prop a un elemento img:
Destrutturare le props
È possibile prendere l'oggetto props ricevuto e destrutturarlo in singole variabili:
Passare props diverse da stringhe
In questo esempio vediamo come passare dei valori booleani, numerici o addirittura degli array come props, inserendoli tra parentesi graffe (ricorda che il codice all'interno viene valutato come semplice JavaScript):
Introduzione a NextJS
Creare l'app di esempio
npx create-next-app@latest
Scelte:
Se da il seguente errore (permessi) Usare il seguente comando:
Se vi compare un errore relativo all'aggiornamento di npm o altro fate così:
npm install -g npm@latest
Se compare un errore relativo all'esecuzione di script in PowerShell aprirla come amministratore ed eseguire:
Set-ExecutionPolicy Unrestricted
#todo
Apri la cartella dell'applicazione su Visual Studio Code
Riconoscimento TAG in nextJS:
Vai su File → Preferenze → Impostazioni
cerca emmet.includeLanguages
completa come nella foto
Dal terminale:
npm run dev
#todo
Apri nel browser l'url dell'applicazione:
Collegarsi via Browser a localhost:3000
Modificare la pagina iniziale
#todo
Apri pages/index.js e modificalo in modo che appaia così:
Da quale file vengono importati gli stili CSS? Come vengono usati poi all'interno della pagina?
Creare altre pagine
Creiamo una nuova pagina inserendo un nuovo file .js nella cartella pages:
Le rotte
pages/index.js sarà associato alla rotta / pages/posts/primo-post.js sarà associato alla rotta /posts/primo-post
#todo
Usa il browser per visitare la nuova pagina.
Il componente Link
Apriamo index.js e importiamo il componente: Lo usiamo poi per modificare il link che compare nel titolo:
Il componente Link non è un semplice link: si occupa anche di precaricare le pagine che il visitatore potrebbe selezionare, in modo da rendere l'esperienza di navigazione più reattiva e veloce.
Il componente Head
Nota che in index.js viene fatto uso del componente Head per impostare il titolo della pagina e importare la favicon.
#todo
Usa quello che hai imparato per creare anche nella pagina primo-post un link che rimanda alla home, inserendolo dentro un elemento h2. Inserisci anche il componente Head per personalizzare il title della pagina.
Creare il componente Layout
Creiamo un componente Layout che sarà condiviso da tutte le pagine. Ci servirà per definire gli stili del sito. Lo metteremo nella cartella components:
#todo
Vai nella pagina primo-post e importa il componente appena creato.
Usiamo poi il componente per racchiudere tutto il contenuto della pagina:
Definire stili CSS
Andremo ora a collegare degli stili CSS al componente Layout:
Per usare questa classe container appena definita dentro al componente layout dobbiamo importare il file CSS e assegnargli un nome (styles). Potremo quindi usarlo nell'attributo className del div:
Il modulo CSS creerà per noi una classe layout_container__2t4v2 ... potremo quindi creare delle classi con nomi semplici nei diversi moduli senza preoccuparci che possano interferire le une con le altre. Inoltre Next.js si occuperà di caricare solo i moduli necessari, rendendo il caricamento della pagina più veloce.
Stili globali
Per caricare degli stili CSS in tutte le pagine dell'applicazione, crea questo file:
App è un componente React di alto livello che racchiude tutte le pagine dell'applicazione: in questo modo sarà possibile mantenere lo stato navigando tra le varie pagine, o aggiungere degli stili globali come stiamo facendo.
Rifinitura del layout
Crea una cartella images dentro a public. Salva al suo interno una foto profilo di circa 500 x 500 pixel.
Il componente Image di Next.js ottimizza il caricamento delle immagini: agli schermi piccoli saranno inviate versioni ridotte dell'immagine, e le immagini saranno caricate solo quando l'utente scrollerà sulla parte della pagina che le contiene (lazy loading).
Aggiungi queste classi al modulo CSS del componente Layout:
Sostituisci il codice del componente Layout con il seguente, mettendo il tuo nome nella variabile name:
import Head from 'next/head';
import Image from 'next/image';
import styles from './layout.module.css';
import utilStyles from '../styles/utils.module.css';
import Link from 'next/link';
const name = 'Your Name';
export const siteTitle = 'Next.js Sample Website';
export default function Layout({ children, home }) {
return (
<div className={styles.container}>
<Head>
<link rel="icon" href="/favicon.ico" />
<meta
name="description"
content="Learn how to build a personal website using Next.js"
/>
<meta
property="og:image"
content={`https://og-image.vercel.app/${encodeURI(
siteTitle,
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
/>
<meta name="og:title" content={siteTitle} />
<meta name="twitter:card" content="summary_large_image" />
</Head>
<header className={styles.header}>
{home ? (
<>
<Image
priority
src="/images/profile.jpg"
className={utilStyles.borderCircle}
height={144}
width={144}
alt=""
/>
<h1 className={utilStyles.heading2Xl}>{name}</h1>
</>
) : (
<>
<Link href="/">
<Image
priority
src="/images/profile.jpg"
className={utilStyles.borderCircle}
height={108}
width={108}
alt=""
/>
</Link>
<h2 className={utilStyles.headingLg}>
<Link href="/" className={utilStyles.colorInherit}>
{name}
</Link>
</h2>
</>
)}
</header>
<main>{children}</main>
{!home && (
<div className={styles.backToHome}>
<Link href="/">← Back to home</Link>
</div>
)}
</div>
);
}
Infine aggiorna anche il contenuto di index.js:
import Head from 'next/head';
import Layout, { siteTitle } from '../components/layout';
import utilStyles from '../styles/utils.module.css';
export default function Home() {
return (
<Layout home>
<Head>
<title>{siteTitle}</title>
</Head>
<section className={utilStyles.headingMd}>
<p>[Your Self Introduction]</p>
<p>
(This is a sample website - you’ll be building a site like this on{' '}
<a href="https://nextjs.org/learn">our Next.js tutorial</a>.)
</p>
</section>
</Layout>
);
}
#todo Aggiungi un Link alla pagina primo-post e modifica il testo della home page a tuo piacimento.
Pre-rendering
Gli articoli del blog
Creiamo una nuova cartella posts (diversa da pages/posts) che conterrà un file per ogni post del nostro blog.
Creiamo il file posts/pre-rendering.md:
---
title: 'Two Forms of Pre-rendering'
date: '2020-01-01'
---
Next.js has two forms of pre-rendering: **Static Generation** and **Server-side Rendering**. The difference is in **when** it generates the HTML for a page.
- **Static Generation** is the pre-rendering method that generates the HTML at **build time**. The pre-rendered HTML is then _reused_ on each request.
- **Server-side Rendering** is the pre-rendering method that generates the HTML on **each request**.
Importantly, Next.js lets you **choose** which pre-rendering form to use for each page. You can create a "hybrid" Next.js app by using Static Generation for most pages and using Server-side Rendering for others.
Creiamo il file posts/ssg-ssr.md:
---
title: 'When to Use Static Generation v.s. Server-side Rendering'
date: '2020-01-02'
---
We recommend using **Static Generation** (with and without data) whenever possible because your page can be built once and served by CDN, which makes it much faster than having a server render the page on every request.
You can use Static Generation for many types of pages, including:
- Marketing pages
- Blog posts
- E-commerce product listings
- Help and documentation
You should ask yourself: "Can I pre-render this page **ahead** of a user's request?" If the answer is yes, then you should choose Static Generation.
On the other hand, Static Generation is **not** a good idea if you cannot pre-render a page ahead of a user's request. Maybe your page shows frequently updated data, and the page content changes on every request.
In that case, you can use **Server-Side Rendering**. It will be slower, but the pre-rendered page will always be up-to-date. Or you can skip pre-rendering and use client-side JavaScript to populate data.
Estrazione dei metadati
Ogni post ha una sezione iniziale di metadati (il titolo e la data del post). Per poterli estrarre installiamo la libreria graymatter:
npm install gray-matter
Crea una cartella lib e al suo interno un file posts.js:
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
const postsDirectory = path.join(process.cwd(), 'posts');
export function getSortedPostsData() {
// Get file names under /posts
const fileNames = fs.readdirSync(postsDirectory);
const allPostsData = fileNames.map((fileName) => {
// Remove ".md" from file name to get id
const id = fileName.replace(/\.md$/, '');
// Read markdown file as string
const fullPath = path.join(postsDirectory, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents);
// Combine the data with the id
return {
id,
...matterResult.data,
};
});
// Sort posts by date
return allPostsData.sort((a, b) => {
if (a.date < b.date) {
return 1;
} else {
return -1;
}
});
}
Per il momento non preoccuparti di capire come funziona questo codice: si tratta di una funzione che prende i file dal file system (fs) e legge i metadati di ogni file usando gray-matter.
Creazione dell'indice dei blog
Useremo il metodo getStaticProps() di NextJS per riempire la nostra pagina index coi metadati dei singoli post.
Static generation with data
Nel server di produzione questa funzione viene eseguita una sola volta quando si costruisce il sito (build): NextJS prepara le pagine di HTML vero e proprio che i browser riceveranno. Il caricamento delle pagine così sarà più veloce.
#toDo
Apri la pagina index e importa la funzione creata al passaggio precedente:
import { getSortedPostsData } from '../lib/posts';
Esporta la funzione getStaticProps che informa NextJS del fatto che vuoi procedere a una generazione statica della pagina, dopo aver importato i dati dei post:
La funzione restituisce un oggetto contenente i metadati di tutti i post (allPostsData), che saranno passati quindi sotto forma di props al componente Home della pagina con questa piccola modifica:
Per visualizzare l'elenco dei post creiamo una nuova sezione nel componente Home, sempre all'interno del Layout, in modo che l'elenco venga visualizzato al di sotto della parte introduttiva: Il risultato dovrebbe essere:
Rotte dinamiche
Lista dei percorsi
Crea un file [id].js dentro a pages/posts: le pagine che iniziano e finiscono con le parentesi quadre sono rotte dinamiche in NextJS. e rimuovi pure primo-post.js, che non ci servirà più.
Al suo interno inserisci questo codice:
import Layout from '../../components/layout';
export default function Post() {
return <Layout>...</Layout>;
}
Questa sarà una pagina come le altre, solo che sarà richiamata con l'id del post desiderato, come vedremo dopo.
Apri adesso lib/posts.js e aggiungi questa nuova funzione in fondo al file:
Questa funzione legge tutti i nomi dei file nella cartella posts e prepara un array di oggetti contenenti gli id dei vari post.
#todo
Torna al file pages/posts/[id].js e importa il metodo appena creato. Prendi spunto dall'importazione di getSortedPostsData fatta nella pagina index e... occhio al percorso!
Aggiungi nella pagina [id] il seguente metodo: Esso sarà richiamato al momento del pre-rendering e restituirà l'elenco dei percorsi di tutti i post presenti nel blog... per farlo userà il metodo getAllPostIds che abbiamo creato e importato.
Implementare getStaticProps
Come abbiamo fatto nella pagina index, dobbiamo creare una funzione getStaticProps che sarà utilizzata al momento del Pre-rendering per riempire la pagina di ogni post con i dati presi dal suo file markdown.
Apri lib/posts.js e aggiungi questa funzione:
export function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents);
// Combine the data with the id
return {
id,
...matterResult.data,
};
}
Essa, dato l'id di un post, ne apre il file e usa gray-matter per estrarre i metadati. Apri pages/posts/[id].js e sostituisci questa riga: ...con queste: Nota che abbiamo modificato l'import per importare entrambe le funzioni dal file lib/posts.
Abbiamo poi implementato il famoso metodo getStaticProps che sarà usato al momento del pre-rendering e fornirà al componente Post le props con i dati del singolo post. Facciamo ora in modo che Post usi i dati ricevuti, riscrivendolo in questo modo:
...in apparenza niente di eccezionale, ma prova a pensare come sono state costruite: tu hai scritto l'articolo in formato md inserendo solo titolo, data e testo... tutto il resto lo ha fatto NextJS, e la cosa bella è che adesso che è tutto pronto lo farà anche per gli altri 100 articoli che inserirai in quella cartella. L'altra cosa bella è che se un giorno vorrai cambiare il layout del sito, non avrai bisogno di modificare le pagine di tutti gli articoli, perché si aggiorneranno da sole!
Ecco in sintesi quello che abbiamo fatto:
Renderizzare il markdown
Per fare il render del markdown di ogni post, e cioè trasformare i file md in html con grassetti, ecc. usiamo la libreria remark:
npm install remark remark-html
Importala nel file lib/posts.js, sotto all'importazione di gray-matter:
import { remark } from 'remark';
import html from 'remark-html';
Aggiorna il metodo getPostData in modo che oltre ai metadati estragga anche il testo del post convertendolo in HTML:
Nota: abbiamo aggiunto anche la parola chiave async che ci permetterà di caricare i dati in modo asincrono.
Aggiorna il file pages/posts[id].js in modo che usi await in coppia con l'async che abbiamo appena scritto: e modifica Post in modo che visualizzi anche il contenuto del post, aggiungendo nel posto giusto questa riga:
Nel file [id].js importa il componente Head e modifica Post come suggerito dai commenti: Per formattare le date installiamo questa libreria:
npm install date-fns
Crea un componente Date inserendolo in un nuovo file da denominare in modo opportuno, e da inserire nella cartella opportuna:
import { parseISO, format } from 'date-fns';
export default function Date({ dateString }) {
const date = parseISO(dateString);
return <time dateTime={dateString}>{format(date, 'd MMMM yyyy')}</time>;
}
Importa il componente appena creato dentro a [id].js e usalo per formattare la data del post:
<Date dateString={postData.date} />
#todo
Provate a scoprire come cambiare il formato della data in modo che mostri anche il giorno della settimana, ad es. monday.
Aggiungiamo infine gli stili che abbiamo preparato nel modulo utils, modificando così il componente Post:
Aggiorniamo la nostra pagina index.js in modo che contenga i link ai singoli post. Per prima cosa importa il componente Link come avevamo fatto in Layout, e il componente Date creato poco fa.
Sostituisci quindi il tag <li>...</li> con il seguente: Prova ad andare su index e verifica che i post siano raggiungibili dagli opportuni link.
MateriaUI
Installazione
MUI permette di creare delle splendide interfacce utente. Sito ufficiale: https://mui.com/
Installazione
Con le righe che seguono installiamo i componenti di MUI per poterli usare nella nostra applicazione:
Vengono installati anche il font Roboto e le icone, che di solito sono utili in qualsiasi progetto.
Inserire un componente
Per usare un componente di MUI bisogna prima importarlo nella pagina in cui vogliamo usarlo (ad esempio index.js): Possiamo poi inserirlo dove vogliamo in questo modo: Nella guida di MUI troviamo una pagina completa di esempi che spiega nel dettaglio il componente: https://mui.com/material-ui/react-button/
Premendo il bottone Show the full source possiamo vedere l'esempio completo. Ci interessano in particolare le righe "import": Gli esempi di solito mostrano come inserire il componente nel contesto di una pagina, ad esempio qui sopra vediamo che tre bottoni sono inseriti in un componente Stack.
#todo
Prova a creare un file per il componente BasicButtons col codice visto sopra (non serve la riga che importa React) e a importarlo nella tua pagina index.
Container e Box
Box
Viene usato come wrapper (involucro) per una serie di utility CSS che si vogliono applicare. La prop sx permette di specificare le varie proprietà CSS:
È il classico container che conosciamo già da Bootstrap. La proprietà maxWidth fissa la larghezza massima del container: per schermi più stretti esso si restringe in maniera fluida.
Anche MUI utilizza di default una griglia a 12 colonne.
Il componente viene usato come contenitore (attributo container = true), come elemento contenuto (attributo item = true) o entrambi. Ecco un semplice esempio:
Possiamo specificare la larghezza che un elemento (item) deve avere per un certo breakpoint e per quelli di dimensioni maggiori, che nell'ordine sono:
xs = extra small
sm = small
md = medium
lg = large
xl = extra large
Possiamo definire larghezze multiple, facendo in modo ad esempio che un elemento sia largo 6/12 su schermi extra piccoli (xs) e piccoli (sm) e 4/12 su schermi dal medium (md) in sù:
xs={6} md={4}
L'attributo spacing (che potrebbe essere inserito anche in un sx) specifica la spaziatura tra gli elementi:
<Grid container spacing={12}>
AppBar
#todo
Scegliete uno degli esempi del componente AppBar di MUI e usatelo per creare nella cartella components un componente BarraSuperiore. Usate poi questo componente all'interno del componente Layout per far comparire la barra di navigazione su tutte le pagine del sito.
Il risultato dovrebbe essere il seguente:
Il metodo .map()
In questo esempio viene creato un nuovo array quadrati prendendo ogni numero e calcolandone il quadrato.
Questa operazione viene chiamata mappatura:
A .map() viene passata come argomento una funzione che restituisce il quadrato del numero (num*num).
In questo altro esempio mappiamo ogni nome con una versione dello stesso nome con l'iniziale maiuscola:
Nota: viene passata una funzione anonima usando la sintassi delle funzioni "freccia".
Mapping di array
Possiamo sfruttare il metodo .map per creare una serie di bottoni. Apri il file di una pagina a tua scelta (o creane una nuova) e crea dopo la sezione import un array con i nomi dei bottoni: Crea una nuova sezione che usa il metodo map per mappare ogni stringa in un list item (li): Come vedi map prende ogni singolo elemento dell'array bottoni e lo mette nella variabile temporanea nome. Sarà quindi possibile usare nome per creare il list item corrispondente.
Trasformiamo ora i list item nei rispettivi bottoni, inseriti in un componente Stack di MUI (ricordati di importarlo):
Creazione di componenti
Preparativi
Importiamo nel nostro componente Layout il componente CSS Baseline di MUI, che serve a preparare una base di partenza di stili CSS eleganti e coerenti: https://mui.com/material-ui/react-css-baseline/
Creiamo un tema vuoto: Incapsuliamo tutto il layout dentro al ThemeProvider, e inseriamo CssBaseline in modo che venga usato da tutte le pagine del sito: Inseriamo infine tutto il contenuto della pagina in un container:
Header
Nel componente Layout creiamo un array di oggetti contenenti i link alle varie sezioni del sito... lo faremo poi visualizzare nel menù principale dell'header:
Importiamo il nostro componente Header e inseriamo nel Layout passandogli il titolo del sito e la lista delle sezioni: Andiamo adesso a lavorare nel file del componente Header... Importiamo alcuni componenti di MUI che ci serviranno: Facciamo in modo che il componente riceva le props: titolo e sezioni. Facciamo pulizia nel blocco return e prepariamo un React.Fragment: https://reactjs.org/docs/fragments.html Il Fragment permette di restituire diversi componenti raggruppati.
Restituiamo una prima Toolbar contenente una prima fascia con dei bottoni, del testo, un'icona: Restituiamo inoltre una seconda Toolbar contenente i link alle sezioni del sito:
Nota come abbiamo usato il metodo map per creare i diversi Link partendo dall'array sezioni.
Prepariamo un esempio di post/articolo/notizia che venga messo in evidenza sull'intera larghezza della pagina.
Per prima cose definiamo nella pagina index un oggetto JavaScript con tutti i dettagli del post: Lo passeremo come props del componente che andremo a creare:
Ricordati di importare il componente.
Definiamo quindi il nostro nuovo componente, importando i componenti necessari: Tutto sarà racchiuso in un componente Paper: Sopra l'immagine ci sarà un layer nero con un'opacità del 40%, per facilitare la lettura dei testi: Il testo sarà posizionato solo su metà (6/12) dell'immagine (per gli schermi dal large in sù) grazie a un componente Grid:
Creiamo un array di oggetti contenenti i dati dei post: Inseriamo un componente Grid che ospiterà i post nella pagina index: Definiamo il componente Post, che userà i seguenti componenti di MUI: Esso è composto da un componente Grid item contenente un'area cliccabile dentro la quale abbiamo il testo e l'immagine della Card:
Definiamo nella pagina index un array con i dati delle slide: Importiamo il nostro componente Carousel passandogli le slide: Definiamo il componente Carousel importando i componenti necessari, oltre ad un foglio di stile:
Denominazione dei componenti
Denominiamo il componente MyCarousel per distinguerlo da quello che importiamo nella prima riga, e che ci servirà da base. Nota però che nella pagina index abbiamo importato MyCarousel denominandolo semplicemente Carousel.
Ecco la struttura del componente: Che darà questo risultato: Il foglio di stile è questo:
Transizioni
È possibile cambiare il tipo di transizione agendo su questi attributi del componente che abbiamo importato:
Nella nostra pagina andiamo a leggere (fetch) i dati (data) e li passiamo al componente Page nella fase di build, usando getStaticProps come abbiamo già fatto in precedenza per i post del blog. Nella pagina compare il componente Movies, che riceverà i dati (data) e disegnerà una griglia di card: Ogni card è disegnata usando questo componente MovieCard, che riceve i dati del singolo film:
Il risultato sarà:
Fetch lato client
Vogliamo provare a fare il fetch lato client, e cioè ogni volta che l'utente apre la pagina.
Vantaggi e svantaggi
Il visitatore vedrà sempre i dati più aggiornati, ma questo richiederà un maggiore tempo di esecuzione.
Useremo SWR:
npm install swr
Il componente principale Movies leggerà i dati dall'API e costruirà una griglia con le singole card. Potremo quindi evitare di passargli i dati via props.
I nostri componenti
Introduzione
Lo scopo è realizzare una collezione di componenti React che ci permettano poi di costruire facilmente il sito della scuola e molti altri ancora.
Progetto Open Source
Essendo il nostro un progetto open source nulla vi vieterà di usare un giorno questa collezione di componenti per realizzare dei siti per voi e i vostri clienti.
Preparativi
Requisiti per l'accettazione delle pull request
corretta denominazione del componente e dei file
corretta denominazione e passaggio delle props al componente
uso di componenti MUI e non generici (ad es. Container, Grid, Box e non semplici div)
corrispondenza del layout a quello richiesto
corrispondenza dei font
assenza di file esterni alla propria cartella dev
nomi dei file (ad es. immagini) tutti in minuscolo
Pagine di prova
Nella cartella /pages/dev (development) create una cartella con il nome breve della vostra organizzazione e lì dentro create una pagina index.js (più eventuali altre pagine che vorrete creare): In queste pagine potrete provare a usare i componenti che creerete, per vedere come appaiono nel contesto del layout generale del sito.
Denominazione e posizione dei componenti
Anche nella cartella /dev create una sottocartella con il nome della vostra organizzazione e lì dentro create tutti i vostri componenti:
Denominazione dei componenti
Il nome del componente deve corrispondere a quello specificato nel listino qui su books. Il nome del file deve essere uguale a quello del componente (maiuscole comprese), con l'aggiunta dell'estensione .js
Link utili
La pagina index della vostra organizzazione sarà raggiungibile da un indirizzo del tipo:
Componente sviluppato da Filippo Bagnoli, Valentina Segato, Elia Barbaric, Lorenzo Alberti, 2F 2022-23
Useremo questo componente nella home page: oltre a un'immagine e a un testo d'impatto conterrà un bottone che permetterà di raggiungere una pagina da mettere in evidenza. In alto a sinistra comparirà la scritta siteName, in alto a destra una serie di link che porteranno alle sezioni principali del sito. All'immagine sarà sovrapposta una schermatura nera della quale sarà possibile regolare l'opacità con l'apposito attributo.
let menu = [
{ title: 'Informatico', url: '/informatico' },
{ title: 'Energie', url: '/energie' },
{ title: 'Elettrico', url: '/elettrico' },
{ title: 'Meccanico', url: '/meccanico' },
{ title: 'Motoristico', url: '/motoristico' },
{ title: 'Carrozzeria', url: '/carrozzeria' },
{ title: 'Trasparenza', url: '/trasparenza' },
]
<LandingHero
siteName="CFP DON BOSCO"
title="Your Story Starts With Us."
description="Every landing page needs a small description......."
imageUrl="https://url.dell.immagine"
opacity={ 0.7 }
buttonText="WATCH VIDEO"
buttonUrl="https://....."
menu={ menu }
height={ 80 }
/>
I parametri buttonText, buttonUrl e menu sono opzionali
Carousel
Definiamo nella pagina index un array con i dati delle slide:
let slides = [
{
titolo: 'Fatti un bel giro',
descrizione: 'Scopri tutti i segreti del nostro Centro con il tour virtuale!',
immagine: 'https://source.unsplash.com/random',
colore: "#ED4C67",
opacity: 0.5,
blur: "0.5rem",
buttonText: 'Scopri di più!',
buttonUrl: 'https:...',
},
{
titolo: 'Concorso nazionale settore elettrico',
descrizione: "A maggio il nostro Centro avrà l'onore di ospitare il Concorso Nazionale del Settore Elettrico: tutti i Centri di Formazione Professionale salesiani d'Italia invieranno i loro campioni per una settimana di sfida e condivisione professionale...",
colore: '#22aa22',
colore2: 'transparent', // opzionale, per realizzare gradienti, può essere un rgba e viene comunque usata anche opacity
},
]
buttonText e buttonUrl sono facoltative; se buttonUrl non è presente il bottone non viene visualizzato.
Importiamo il nostro componente Carousel passandogli le slide e la larghezza desiderata (false fa sì che il carousel si estenda all'intero schermo):
Componente sviluppato da Alessio Solighetto e Daniel Solighetto, 2F 2022-23
Mette in evidenza i nostri punti di forza. Riceve un titolo, una descrizione e un array contenente un oggetto per ogni punto di forza. L'attributo cardWidth specifica la larghezza delle singole colonne... nell'esempio sopra abbiamo tre colonne che occupano ognuna i 4/12 della larghezza della pagina. Se l'array features dovesse contenere un numero maggiore di oggetti, questi dovrebbero andare a capo.
let features = [
{
imageUrl: "https....",
title: "Free Chat",
description: "Divide details about..."
},
...
]
<Features
title="Why our product is the best"
description="This is the paragraph......."
features={ features }
cardWidth={ 4 }
/>
Team
Componente sviluppato da Filippo Urban e Zaccaria Cesaro, 2F 2022-23
Presenta i membri del team. Riceve un titolo, una descrizione e un array contenente un oggetto per ogni membro. L'attributo cardWidth specifica la larghezza delle singole colonne... nell'esempio sopra abbiamo quattro colonne che occupano ognuna i 3/12 della larghezza della pagina. Se l'array members dovesse contenere un numero maggiore di oggetti, questi dovrebbero andare a capo.
let members = [
{
name: "Alec Thompson",
role: "CEO / CO-FOUNDER",
description: "And I love you like...",
imageUrl: "https..."
linkedinUrl: "https...",
facebookUrl: "https...",
instagramUrl: "https...",
maxWidth: "lg"
},
...
]
<Team
title="Our Awesome Team"
description="This is the paragraph......."
members={ members }
cardWidth={ 3 }
/>
Products
Componente sviluppato da Lorenzo Alberti e Elia Barbaric, 2F 2022-23
Presenta una serie di prodotti in evidenza. Riceve un titolo, una descrizione e un array contenente un oggetto per ogni prodotto. L'attributo cardWidth specifica la larghezza delle singole colonne... nell'esempio sopra abbiamo tre colonne che occupano ognuna i 4/12 della larghezza della pagina. Se l'array products dovesse contenere un numero maggiore di oggetti, questi dovrebbero andare a capo.
let products = [
{
title: "NextJS Material Kit Free",
category: "FREE UI KIT",
description: "It is a Fre Material-UI Kit with.....",
immagineUrl: "https:...",
url: "https..."
},
...
]
<Products
title="Some of Our Awesome Products"
description="This is the paragraph......."
products={ products }
cardWidth={ 4 }
borderRadius="10px"
aspectRatio="3 / 2"
/>
Testimonials
Componente sviluppato da Alessio Solighetto e Daniel Solighetto, 2F 2022-23
Presenta una serie di recensioni da parte dei clienti. Riceve un titolo, una descrizione e un array contenente un oggetto per ogni recensione. L'attributo cardWidth specifica la larghezza delle singole colonne... nell'esempio sopra abbiamo tre colonne che occupano ognuna i 4/12 della larghezza della pagina. Se l'array testimonials dovesse contenere un numero maggiore di oggetti, questi dovrebbero andare a capo.
let testimonials = [
{
name: "Alec Thompson",
channel: "@Google",
text: "Your produtcs, all the kits.......",
imageUrl: "https..."
},
...
]
<Testimonials
title="Our Clients Love Us"
description="You need more informations?....."
imageUrl="https....."
opacity={0.7}
testimonials={ testimonials }
cardWidth={ 4 }
/>
Footer
Componente sviluppato da Bilal Amara, Thiago Alves Rodrigues e Dionise Rotaru, 2F 2022-23
Footer che apparirà sul fondo di tutte le pagine del sito. Sarà possibile passare al componente un'immagine di sfondo opzionale oppure un colore di sfondo. L'attributo opaciy permetterà di sovrapporre all'immagine un Box con il colore di sfondo e un'opacità regolabile. La prima colonna sarà destinata a un testo descrittivo, la seconda ai social, la terza a un menù di navigazione grafico (che porta ad es. ai settori). Sul fondo compariranno un ulteriore menù personalizzabile e una nota di copyright.
Un paragrafo di testo inserito in un container, con un colore di sfondo opzionale e un'immagine collegata.
<Paragraph
title="Risotto con gli asparagi"
subtitle="Una specialità tutta nostrana"
topImageUrl="https..."
avatarImageUrl="https..."
leftImageUrl="https..."
rightImageUrl="https..."
backgroundImageUrl="https..."
backgroundColor="#225533"
opacity={0.8}
blur="0.2rem"
color="white"
columnCount={1}
maxWidth="lg"
sx={{...}}
>
Qui va tutto il testo del paragrafo...
</Paragraph>
Gli attributi sono tutti opzionali.
Maps
Componente sviluppato da Filippo Bagnoli e Valentina Segato, 2F 2022-23
<Calendar title="Prima settimana" cardWidth={3} events={settimana1} />
let settimana1 = [
{
date: "Lunedì 19 Giugno",
morning: "Attività regolare",
afternoon: "Giochi al parco e tornei",
evening: "ore 20.45 Film TRANSFORMERS - IL RISVEGLIO",
immagineUrl: "/images/calendario/transformers.png",
},
];
Props opzionali:
aspectRatio="3 / 2" // proporzioni di ritaglio delle immagini
News
<News title={null} data={data} />
Props opzionali:
limit={6} // numero massimo di post presentati
aspectRatio="3 / 2" // proporzioni di ritaglio delle immagini
È possibile usare SwiperNews al posto di News, con le stesse props: viene visualizzato come slider. Entrambi fanno usp di un componente NewsCard apposito.
Ricevono i dati via API dal backend channels.
Featured
<Featured data={data} />
Featured si appoggia al componente Carousel. Props opzionali:
limit: 6 // numero massimo di post presentati
maxWidth: false // larghezza del container
height: 90 // altezza del container
Moduli CSS: prendere l'abitudine di mettere gli stili nel modulo, come con React Native
Render di array di oggetti
Layout come componente wrapper: props.children
Form
Firebase offre un database e le API per interrogarlo. In test mode. Facciamo una richiesta http di tipo POST. Potremmo usare axios che è una libreria di uso molto comune, ma qui lo facciamo col fetch. Fetch di default fa richieste GET.
L'url viene trattato come una cartella / una tabella: I dati inviati sono visibili su Firebase: Dopo aver fatto il post torniamo alla home:
Fetching data
Stesso URL, ma stavolta con GET. Ciclo infinito: cambia lo stato e rifà il fetch e via così. useEffect permette di eseguire codice sotto certe condizioni. Primo argomento: una funzione che contiene il codice da eseguire Secondo argomento: array di dipendenze che vengono valutate... il codice viene eseguito solo se il loro valore cambia. Se è vuoto React esegue la funzione solo la prima volta. Le dipendenze sono i valori esterni alla funzione da cui essa dipende... se non cambiano non viene rivalutata.
Firebase non restituisce un array ma un oggetto che ha come proprietà gli id degli elementi: Non possiamo usare semplicemente il .map()
Context
Vogliamo usare lo stato in diversi componenti. Lift State: lo portiamo a livello di App.js e poi passiamo le parti necessarie come props ai singoli componenti. Per applicazioni grandi il componente App diventa sempre più grande, e abbiamo catene di stato molto lunghe.
Redux è un package per la gestione dello stato, ma React stesso ha una soluzione per la gestione dello stato a livello dell'intera applicazione: Context
Creiamo una cartella /store
I componenti racchiusi nel Context hanno accesso ai dati del Context.