Utilisez
getStaticPropsetgetServerSidePropscomme crochets React
next-data-hooks est une petite et simple lib qui vous permet d'écrire des crochets React pour les requêtes de données dans Next.js en levant des accessoires statiques dans le contexte React.
import { createDataHook } from 'next-data-hooks' ;
const useBlogPost = createDataHook ( 'BlogPost' , async ( context ) => {
const { slug } = context . params ;
return ; // ... get the blog post
} ) ;
function BlogPost ( ) {
const { title , content } = useBlogPost ( ) ;
return (
< >
< h1 > { title } </ h1 >
< p > { content } </ p >
</ >
) ;
}
BlogPost . dataHooks = [ useBlogPost ] ;
export default BlogPost ; La principale chose que cette bibliothèque offre est un modèle organisant getStaticProps / getServerSideProps .
Voir cette question: pourquoi les crochets de données ne sont-ils pas paramétrés?
Voir l'exemple de ce dépôt pour quelques idées sur la façon d'organiser vos appels de données statiques à l'aide de ce crochet.
npm i next-data-hooks
ou
yarn add next-data-hooks
À la racine, ajoutez un fichier .babelrc qui contient ce qui suit:
{
"presets" : [ " next/babel " ],
"plugins" : [ " next-data-hooks/babel " ]
}
️ N'oubliez pas cette étape. Cela permet à l'élimination du code d'éliminer le code côté serveur dans le code client.
_app.tsx ou _app.js import { AppProps } from 'next/app' ;
import { NextDataHooksProvider } from 'next-data-hooks' ;
function App ( { Component , pageProps } : AppProps ) {
const { children , ... rest } = pageProps ;
return (
< NextDataHooksProvider { ... rest } >
< Component { ... rest } > { children } </ Component >
</ NextDataHooksProvider >
) ;
} import { createDataHook } from 'next-data-hooks' ;
// this context is the GetStaticPropsContext from 'next'
// ?
const useBlogPost = createDataHook ( 'BlogPost' , async ( context ) => {
const slug = context . params ?. slug as string ;
// do something async to grab the data your component needs
const blogPost = /* ... */ ;
return blogPost ;
} ) ;
export default useBlogPost ;Remarque: Pour les utilisateurs de TypeScript, si vous prévoyez d'utiliser uniquement le crochet de données dans le contexte de
getServerSideProps, vous pouvez importer le type de type fourni,isServerSidePropsContext, pour affiner le type du contexte entrant.
import { createDataHook , isServerSidePropsContext } from 'next-data-hooks' ;
const useServerSideData = createDataHook ( 'Data' , async ( context ) => {
if ( ! isServerSidePropsContext ( context ) ) {
throw new Error ( 'This data hook only works in getServerSideProps.' ) ;
}
// here, the type of `context` has been narrowed to the server side conext
const query = context . req . query ;
} ) ;
export default useServerSideData ; import ComponentThatUsesDataHooks from '..' ;
import useBlogPost from '..' ;
import useOtherDataHook from '..' ;
function BlogPostComponent ( ) {
const { title , content } = useBlogPost ( ) ;
const { other , data } = useOtherDataHook ( ) ;
return (
< article >
< h1 > { title } </ h1 >
< p > { content } </ p >
< p >
{ other } { data }
</ p >
</ article >
) ;
}
// compose together other data hooks
BlogPostComponent . dataHooks = [
... ComponentThatUsesDataHooks . dataHooks ,
useOtherDataHooks ,
useBlogPost ,
] ;
export default BlogPostComponent ;getStaticProps ou getServerSideProps . import { getDataHooksProps } from 'next-data-hooks' ;
import { GetStaticPaths , GetStaticProps } from 'next' ;
import BlogPostComponent from '..' ;
export const getStaticPaths : GetStaticPaths = async ( context ) => {
// return static paths...
} ;
// NOTE: this will also work with `getServerSideProps`
export const getStaticProps : GetStaticProps = async ( context ) => {
const dataHooksProps = await getDataHooksProps ( {
context ,
// this is an array of all data hooks from the `dataHooks` static prop.
// ???
dataHooks : BlogPostComponent . dataHooks ,
} ) ;
return {
props : {
// spread the props required by next-data-hooks
... dataHooksProps ,
// add additional props to Next.js here
} ,
} ;
} ;
export default BlogPostComponent ; routes distinct Next.js a un mécanisme de routage basé sur des fichiers très opiniâtre qui ne vous permet pas de mettre un fichier dans le dossier /pages sans qu'il soit considéré comme une page.
Autrement dit, cela ne permet pas beaucoup d'organisation.
Avec next-data-hooks , vous pouvez traiter le dossier /pages comme un dossier de points d'entrée et organiser des fichiers ailleurs.
my-project
# think of the pages folder as entry points to your routes
├── pages
│ ├── blog
│ │ ├── [slug].ts
│ │ └── index.ts
│ └── shop
│ ├── category
│ │ └── [slug].ts
│ ├── index.ts
│ └── product
│ └── [slug].ts
|
# think of each route folder as its own app with it's own components and helpers
└── routes
├── blog
│ ├── components
│ │ ├── blog-index.tsx
│ │ ├── blog-post-card.tsx
│ │ └── blog-post.tsx
│ └── helpers
│ └── example-blog-helper.ts
└── shop
├── components
│ ├── category.tsx
│ ├── product-description.tsx
│ └── product.tsx
└── helpers
└── example-shop-helper.ts
/routes/blog/components/blog-post.tsx import { createDataHook } from 'next-data-hooks' ;
// write your data hook in a co-located place
const useBlogPostData = createDataHook ( 'BlogPost' , async ( context ) => {
const blogPostData = // get blog post data…
return blogPostData ;
} ) ;
function BlogPost ( ) {
// use it in the component
const { title , content } = useBlogPostData ( ) ;
return (
< article >
< h1 > { title } </ h1 >
< p > { content } </ p >
</ article >
) ;
}
BlogPost . dataHooks = [ useBlogPostData ] ;
export default BlogPost ; /pages/blog/[slug].ts import { GetStaticProps , GetStaticPaths } from 'next' ;
import { getDataHooksProps } from 'next-data-hooks' ;
import BlogPost from 'routes/blog/components/blog-post' ;
export const getStaticPaths : GetStaticPaths = { } ; /* ... */
export const getStaticProps : GetStaticProps = async ( context ) => {
const dataHooksProps = getDataHooksProps ( {
context ,
dataHooks : BlogPost . dataHooks ,
} ) ;
return { props : dataHooksProps } ;
} ;
// re-export your component. this file is just an entry point
export default BlogPost ;Remarque: Ce qui précède est juste un exemple de la façon dont vous pouvez utiliser
next-data-hookspour organiser votre projet. Le principal point à retenir est que vous pouvez réexporter des composants de la page pour modifier la structure etnext-data-hooksfonctionnent bien avec ce modèle.
Chaque crochet de données expose une méthode getData qui est simplement la fonction que vous transmettez dans createDataHook .
Cela peut être utilisé dans d'autres crochets de données pour extraire les mêmes données:
import { createDataHook } from 'next-data-hooks' ;
const useHook = createDataHook ( 'DataHook' , async ( context ) => {
return ; // ...
} ) ;
export default useHook ; import useHook from './' ;
const useOtherHook = createDataHook ( 'Other' , async ( context ) => {
const data = await useHook . getData ( context ) ;
// use data to do something…
} ) ;Remarque: sachez que cette méthode réinstalle la fonction.
Pour les petits paquets, Next.js élimine le code qui est uniquement destiné à s'exécuter à l'intérieur getStaticProps .
next-data-hooks font la même chose par un plugin Babel qui préfixe votre définition de crochet de données avec typeof window !== 'undefined' ? <stub> : <real data hook> .
Cela fonctionne parce que Next.js pré-évalue la typeof window à 'object' dans les navigateurs. Cela fera que le ternaire ci-dessus évaluera toujours le <stub> dans le navigateur. Terser secoue ensuite l'expression de <real data hook> l'éliminer du faisceau du navigateur.
Si vous avez vu l'erreur Create data hook was run in the browser. Ensuite, quelque chose a peut-être mal tourné avec l'élimination du code. Veuillez ouvrir un problème.
Note . Il peut y avoir des différences dans l'élimination du code par défaut de Next.js et l'élimination du code
next-data-hooks. Vérifiez votre paquet.