Strategieën voor het ophalen van gegevens in NextJS
Pawel Rybczynski
Software Engineer
De laatste tijd wint NextJS steeds meer aan populariteit als een manier om React toepassingen te bouwen. Het feit dat NextJS verschillende strategieën voor het ophalen van gegevens biedt, draagt hier zeker aan bij.
En dat zijn:
Weergave aan de klantzijde: CSR,
Rendering aan serverzijde: SSR,
Statische site rendering: SSG,
Incrementele statische regeneratie: ISR.
NextJS biedt, in tegenstelling tot de gewone React app, een functie die pre-rendering heet. Dit betekent dat vooraf gerenderde HTML wordt weergegeven tijdens de eerste lading. In traditionele React applicaties wordt de hele app geladen en gerenderd aan de kant van de client. Vervolgens, nadat de JS code is geladen, wordt de toepassing interactief.
Statische generatie
In SSG wordt de HTML tijdens het bouwen gegenereerd en hergebruikt voor elke aanvraag. Nadat een productieversie is gemaakt, zal elk verzoek dat statisch gegenereerde HTML-bestand opnieuw gebruiken.
Er zijn ook twee soorten statische generatie: met en zonder gegevens.
In het eerste geval wordt de HTML gegenereerd na het ophalen van de gegevens door de belofte op te lossen. In dit geval kunnen we de methode voor het ophalen van gegevens getStaticProps gebruiken... maar alleen als je Next.js 9.3 of nieuwer gebruikt. Zo niet, denk er dan over na om te upgraden, want de oudere methode getInitialProps wordt niet langer aanbevolen en zal deprecated worden. Deze methode wordt ook bij elke client-side navigatie aangeroepen, dus het is niet efficiënt als je niet bij elk verzoek gegevens wilt ophalen.
Wat echt cool is, is een nieuw uitgebrachte functie genaamd ISR (Incremental Static Regeneration), die iets tussen SSG en SSR in zit. Hiermee kun je (met behulp van een specifieke sleutel genaamd revalidate) de pagina incrementeel regenereren. Dit betekent dat je met deze sleutel de app niet elke keer opnieuw hoeft te bouwen als je een update wilt van de gegevens die van de server zijn gehaald. Voeg gewoon de revalidate sleutel toe met de revalidatieperiode in seconden.
Dit betekent dat als er na die periode verzoeken komen, de gegevens opnieuw van de server worden gehaald.
Een andere situatie is wanneer je een dynamische pagina gebruikt en het pad afhankelijk is van externe gegevens. In dat geval kunnen we de methode getStaticPaths gebruiken om te vertellen welke dynamische routes vooraf geladen moeten worden:
export async const getStaticProps = ({params }) => {
const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`);
const post = await res.json();
return {
props: { post },
};
}
Er is een mooie manier om te controleren welke dynamische routes zijn gemaakt. Je kunt de volgende build en de volgende export uitvoeren en daarna heb je een statische versie van je app in de nieuw aangemaakte out directory.
Na het uitvoeren van de volgende export, zien we in beide gevallen (met en zonder een beperkt aantal paden) een verschillend aantal berichten gevonden in mijn-appoutposts.
Laten we nu eens kijken naar de cruciale en vereiste fallback parameter. Deze zegt wat er moet gebeuren als de pagina niet vooraf is gerenderd tijdens het bouwen. Als deze is ingesteld op true, wordt getStaticProps uitgevoerd en wordt die pagina gegenereerd. Als deze parameter false is, krijgen we 404 als we dat specifieke pad proberen te laden. Nog iets: pagina's met fallback die zijn ingeschakeld in getStaticPaths kunnen niet worden geëxporteerd.
Hieronder zie je de resultaten van het laden van dezelfde dynamische pagina in beide gevallen:
Eerste geval (zonder beperkte paden)
Tweede geval (met beperkte paden en fallback ingesteld op false)
Tweede geval (met beperkte paden en fallback ingesteld op waar)
Rendering op de server
Het belangrijkste verschil met SSG: er wordt bij elke aanvraag nieuwe HTML gegenereerd. Dit wordt vooral gebruikt als we externe gegevens ophalen. In dit geval is het niet nodig om de app elke keer opnieuw te bouwen als we de gegevens van de server willen bijwerken.
De methode getServerSideProps lijkt erg op getStaticProps. Het verschil is dat getServerSideProps bij elke aanvraag wordt uitgevoerd, terwijl getStaticProps eenmalig in build-time wordt uitgevoerd.
Rendering aan de klantzijde
Met client-side rendering is het laden van de pagina in eerste instantie een beetje traag. De communicatie met de server gebeurt in de runtime. Je kunt het op een meer traditionele manier doen:
We kunnen ook een andere oplossing gebruiken, 'swr' - React Hooks library voor het ophalen van gegevens door Vercel*, die sterk wordt aanbevolen door de makers van NextJS. SWR staat voor State While Revalidate.
import useSWR uit "swr";
const Blog = () => {
const fetcher = (url) => fetch(url).then((r) => r.json());
const {data: berichten = [], fout } = useSWR(
"https://jsonplaceholder.typicode.com/posts", fetcher);
Als (fout) retourneer <div>Berichten niet geladen</div>;
Als (!posts.length) terugkeren <div>laden...</div>;
retour (
<>
{posts.map((post) => (
{post.title}
))}
</>
}
Samenvatting
NextJS geeft ons de extra mogelijkheid om te kiezen welke van de data fetching strategieën we willen gebruiken op elke pagina. We hoeven niet slechts één oplossing te volgen voor de hele applicatie.
Snelkoppeling
getServerSideProps - als je app moet pre-render bij elke aanvraag met opgehaalde gegevens
getStaticProps - als de gegevens één keer kunnen worden opgehaald tijdens het bouwen en bij elke aanvraag kunnen worden gebruikt zonder bij te werken
getInitialProps - niet aanbevolen, wordt afgeschreven
getStaticPaths - voor het vooraf renderen van dynamische paden