Next.js Tutorial - Part 8 - Static Site Generation getStaticProps and getStaticPaths currentPage 3

https://github.com/mui-org/material-ui/tree/master/examples/nextjs/pages

get currentPage

C:\Users\Administrator\Desktop\abc\pages\_app.js

import AppBar from '@material-ui/core/AppBar';
import Box from '@material-ui/core/Box';
import Container from '@material-ui/core/Container';
import CssBaseline from '@material-ui/core/CssBaseline';
import IconButton from '@material-ui/core/IconButton';
import { ThemeProvider } from '@material-ui/core/styles';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import MenuIcon from '@material-ui/icons/Menu';
import App from 'next/app';
import Head from 'next/head';
import React from 'react';
import theme from '../theme';
export default class MyApp extends App {
  componentDidMount() {
    // Remove the server-side injected CSS.
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles) {
      jssStyles.parentElement.removeChild(jssStyles);
    }
  }
  render() {
    const { Component, pageProps } = this.props;
    return (
      <React.Fragment>
        <Head>
          <title>My page</title>
          <meta
            name="viewport"
            content="minimum-scale=1, initial-scale=1, width=device-width"
          />
        </Head>
        <AppBar position="fixed">
          <Toolbar variant="dense">
            <IconButton edge="start" color="inherit" aria-label="menu">
              <MenuIcon />
            </IconButton>
            <Typography variant="h6">Microphone Shop</Typography>
          </Toolbar>
        </AppBar>
        <ThemeProvider theme={theme}>
          {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
          <CssBaseline />
          <Container>
            <Box marginTop={8}>
              <Component {...pageProps} />
            </Box>
          </Container>
        </ThemeProvider>
      </React.Fragment>
    );
  }
}

C:\Users\Administrator\Desktop\abc\pages\_document.js

import { ServerStyleSheets } from '@material-ui/core/styles';
import Document, { Html, Head, Main, NextScript } from 'next/document'
import React from 'react';
import theme from '../theme';

export default class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          {/* PWA primary color */}
          <meta name="theme-color" content={theme.palette.primary.main} />
          <link
            rel="stylesheet"
            href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

MyDocument.getInitialProps = async ctx => {
  // Resolution order
  //
  // On the server:
  // 1. app.getInitialProps
  // 2. page.getInitialProps
  // 3. document.getInitialProps
  // 4. app.render
  // 5. page.render
  // 6. document.render
  //
  // On the server with error:
  // 1. document.getInitialProps
  // 2. app.render
  // 3. page.render
  // 4. document.render
  //
  // On the client
  // 1. app.getInitialProps
  // 2. page.getInitialProps
  // 3. app.render
  // 4. page.render

  // Render app and page and get the context of the page with collected side effects.
  const sheets = new ServerStyleSheets();
  const originalRenderPage = ctx.renderPage;

  ctx.renderPage = () =>
    originalRenderPage({
      enhanceApp: App => props => sheets.collect(<App {...props} />),
    });

  const initialProps = await Document.getInitialProps(ctx);

  return {
    ...initialProps,
    // Styles fragment is rendered after the app and page rendering finish.
    styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
  };
};

C:\Users\Administrator\Desktop\abc\pages\index.tsx

import { Grid } from '@material-ui/core';
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Typography from '@material-ui/core/Typography';
import { GetStaticProps } from 'next';
import Link from 'next/link';
import { Microphone } from '../../model/Microphone';
import  openDB  from '../openDB';
export interface IndexProps {
  microphones: Microphone[];
}
export default function Index({ microphones }: IndexProps) {
  return (
    <Grid container spacing={3}>
      {microphones.map((microphone) => (
        <Grid item xs={12} sm={3} key={microphone.id}>
          <Link href="/microphone/[id]" as={`/microphone/${microphone.id}`}>
            <a>
              <Card>
                <CardActionArea>
                  <CardMedia
                    component="img"
                    alt={microphone.brand + ' ' + microphone.model}
                    height="300"
                    image={microphone.imageUrl}
                    title={microphone.brand + ' ' + microphone.model}
                  />
                  <CardContent>
                    <Typography gutterBottom variant="h5" component="h2">
                      {microphone.brand + ' ' + microphone.model}
                    </Typography>
                    <Typography
                      variant="body2"
                      color="textSecondary"
                      component="p"
                    >
                      Lizards are a widespread group of squamate reptiles, with
                      over 6,000 species, ranging across all continents except
                      Antarctica
                    </Typography>
                  </CardContent>
                </CardActionArea>
              </Card>
            </a>
          </Link>
        </Grid>
      ))}
    </Grid>
  );
}
export const getStaticProps: GetStaticProps = async (ctx) => {
  console.log(ctx);
  const currentPage = ctx.params?.currentPage as string;
  const currentPageNumber = +(currentPage || 0);
  const min = currentPageNumber * 5;
  const max = (currentPageNumber + 1) * 5;
  const db = await openDB();
  const microphones = await db.all(
    'select * from microphone where id > ? and id <= ?',
    min,
    max
  );
  return { props: { microphones } };
};

C:\Users\Administrator\Desktop\abc\pages[currentPage].tsx

import { GetStaticPaths } from 'next';
import  openDB  from '../openDB';
import Index, { getStaticProps } from './';
export default Index;
export { getStaticProps };
export const getStaticPaths: GetStaticPaths = async () => {
    const db = await openDB();
    const { total } = await db.get('select count(*) as total from microphone');
    const numberOfPages = Math.ceil(total / 5.0);
    const paths = Array(numberOfPages- 1).fill('').map((_, index) => {
        return { params: {currentPage: (index + 1).toString()}}
      })
  return {
    fallback: false,
    paths: paths,
  };
};

Thư viện

Cách phân trang khá độc lạ

pages\index.tsx

import type { GetStaticProps, NextPage } from 'next';
import openDB from '../pages/openDB';
import {Microphone} from './model/Microphone';
export interface IndexProps {
	microphones: Microphone[]
}
import styles from '../styles/Home.module.css'
import Link from 'next/link';
const Home: any = ({microphones}: IndexProps) => {
  return (
    <div className={styles.container}>
      <main className={styles.main}>
        {
          microphones?.map((microphone) => {
            return (
              <Link className='block' href="/microphone/[id]" as={`/microphone/${microphone.id}`} key={microphone.id}>
                {microphone.brand + " " + microphone.model + " " + microphone.price}
              </Link>
            )
          })
        }
      </main>
    </div>
  )
}
export default Home
export const getStaticProps: GetStaticProps = async (ctx) => {
  const currentPage = ctx.params?.currentPage as string;
  const currentPageNumber = +(currentPage || 0);
  const min = currentPageNumber * 5;
  const max = (currentPageNumber + 1) * 5;
  const db = await openDB();
  const microphones = await db.all(
    'select * from microphone where id > ? and id <= ?',min,max
  );
  return { props: { microphones } };
};

pages[currentPage].tsx

import { GetStaticPaths } from 'next';
import openDB from '../pages/openDB';
import Index, { getStaticProps } from './';
export default Index;
export { getStaticProps };
export const getStaticPaths: GetStaticPaths = async () => {
  const db = await openDB();
  const { total } = await db.get('select count(*) as total from microphone');
  const numberOfPages = Math.ceil(total / 5.0);
  const paths = Array(numberOfPages - 1).fill('').map((_, index) => {
    return { 
      params: { 
        currentPage: (index + 1).toString() 
      } 
    }
  });
  return {
    fallback: false,
    paths: paths,
  };
}

Page 0

Page 1

Last updated

Was this helpful?