ใช้
getStaticPropsและgetServerSidePropsเป็น hooks ตอบสนอง
next-data-hooks เป็น LIB ขนาดเล็กและเรียบง่ายที่ให้คุณเขียน hooks React สำหรับการสืบค้นข้อมูลใน next.js โดยการยกอุปกรณ์ประกอบฉากคงที่เป็นบริบทการตอบสนอง
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 ; สิ่งสำคัญคือไลบรารีนี้คือการจัดรูปแบบ การจัดระเบียบ getStaticProps / getServerSideProps
ดูคำถามนี้: ทำไมข้อมูลไม่ได้กำหนดพารามิเตอร์?
ดูตัวอย่างใน repo นี้สำหรับแนวคิดบางอย่างเกี่ยวกับวิธีการจัดระเบียบข้อมูลการโทรแบบคงที่ของคุณโดยใช้ตะขอนี้
npm i next-data-hooks
หรือ
yarn add next-data-hooks
ที่รูทเพิ่มไฟล์ .babelrc ที่มีสิ่งต่อไปนี้:
{
"presets" : [ " next/babel " ],
"plugins" : [ " next-data-hooks/babel " ]
}
อย่าลืมขั้นตอนนี้ สิ่งนี้ช่วยให้ การกำจัดรหัส เพื่อกำจัดรหัสฝั่งเซิร์ฟเวอร์ในรหัสไคลเอนต์
_app.tsx หรือ _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 ;หมายเหตุ: สำหรับผู้ใช้ TypeScript หากคุณกำลังวางแผนที่จะใช้ Data Hook เฉพาะในบริบทของ
getServerSidePropsคุณสามารถนำเข้าอุปกรณ์ป้องกันประเภทที่ให้ไว้,isServerSidePropsContextเพื่อ จำกัด ประเภทของบริบทที่เข้ามา
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 หรือ 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 แยกต่างหาก Next.js มีกลไกการกำหนดเส้นทางตามไฟล์ที่มีความคิดเห็นเป็นอย่างมากซึ่งไม่อนุญาตให้คุณใส่ไฟล์ในโฟลเดอร์ /pages โดยไม่ต้องพิจารณาหน้า
พูดง่ายๆคือสิ่งนี้ไม่อนุญาตให้มีองค์กรมากนัก
ด้วย next-data-hooks คุณสามารถปฏิบัติต่อโฟลเดอร์ /pages เป็นโฟลเดอร์ของจุดเข้าและจัดระเบียบไฟล์ที่อื่น
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 ;หมายเหตุ: ข้างต้นเป็นเพียงตัวอย่างของวิธีที่คุณสามารถใช้
next-data-hooksในการจัดระเบียบโครงการของคุณ สิ่งที่สำคัญคือคุณสามารถส่งออกส่วนประกอบหน้าเพื่อเปลี่ยนโครงสร้างและnext-data-hooksทำงานได้ดีกับรูปแบบนี้
ตะขอข้อมูลแต่ละครั้งจะเปิดเผยวิธี getData ซึ่งเป็นเพียงฟังก์ชั่นที่คุณส่งผ่านไปยัง createDataHook
สามารถใช้ภายในตะขอข้อมูลอื่น ๆ เพื่อดึงข้อมูลเดียวกัน:
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…
} ) ;หมายเหตุ: โปรดทราบว่าวิธีนี้เรียกใช้ฟังก์ชันอีกครั้ง
สำหรับการรวมกลุ่มที่เล็กลง next.js จะกำจัดรหัสที่มีจุดประสงค์เพื่อให้ทำงานภายใน getStaticProps เท่านั้น
next-data-hooks จะทำเช่นเดียวกันโดยปลั๊กอิน Babel ที่นำหน้าคำจำกัดความข้อมูลของคุณด้วย typeof window !== 'undefined' ? <stub> : <real data hook>
สิ่งนี้ใช้งานได้เนื่องจาก next.js ล่วงหน้าประเมิน typeof window นิพจน์ไปยัง 'object' ในเบราว์เซอร์ สิ่งนี้จะทำให้ Ternary ข้างต้นประเมินไปยัง <stub> ในเบราว์เซอร์เสมอ จากนั้นเทอร์เซอร์ก็สั่นสะเทือน <real data hook> expression กำจัดออกจากชุดเบราว์เซอร์
หากคุณเห็นข้อผิดพลาด Create data hook was run in the browser. ถ้าอย่างนั้นก็มีบางอย่างผิดปกติกับการกำจัดรหัส กรุณาเปิดปัญหา
บันทึก . อาจมีความแตกต่างในการกำจัดรหัสเริ่มต้นของ JS Next.js และการกำจัดรหัส
next-data-hooksตรวจสอบชุดของคุณอีกครั้ง