mongodb api 上带有 mui 分页的下一个 js

Next js with mui pagination on mongodb api

我正在 Next js 中为个人网站创建管理仪表板。 我的后端api如下

import nc from 'next-connect';
import Listing from '../../../../models/Notes';
import db from '../../../../utils/db';

const handler = nc();

handler.get(async (req, res) => {
  const { page = 1, limit = 10 } = req.query;
  await db.connect();
  try {
    const notes = await Notes.find()
      .limit(limit * 1)
      .skip((page - 1) * limit)
      .exec();
    const count = await Notes.countDocuments();
    res.json({
      totalPages: Math.ceil(count / limit),
      currentPage: page,
      notes,
    });
  } catch (err) {
    console.error(err.message);
  }
  await db.disconnect();
  // res.send(notes);
});

export default handler;

当我 运行 api 波纹管格式时,这给了我:

{
"totalPages": 27,
"currentPage": "12",
"data": [{},{},...,{},{}]
}

我能够提取信息并将其呈现给前端,但我在数据分页方面遇到了问题。任何提示 - 非常感谢我如何实现这一目标的指示。 以下是我的管理页面代码。

import React, { useContext, useReducer, useEffect, useState } from 'react';
import axios from 'axios';
import dynamic from 'next/dynamic';
import Layout from '../../components/Layout';
import NextLink from 'next/link';
import {
  Grid,
  Card,
  List,
  ListItem,
  ListItemText,
  TableContainer,
  Table,
  TableHead,
  TableBody,
  TableCell,
  TableRow,
  Button,
} from '@mui/material';
import classes from '../../utils/classes';
import { useRouter } from 'next/router';
import { getError } from '../../utils/errors';
import { Store } from '../../utils/Store';
import { useSnackbar } from 'notistack';
import { Pagination } from '@mui/material';

function reducer(state, action) {
  switch (action.type) {
    case 'FETCH_REQUEST':
      return {
        ...state,
        loading: true,
        currentPage: action.payload,
        error: '',
      };
    case 'FETCH_SUCCESS':
      return { ...state, loading: false, notes: action.payload, error: '' };
    case 'NUMBER_OF_PAGES':
      return { ...state, pageCount: action.payload };
    case 'CURRENT_PAGE':
      return { ...state, currentPage: action.payload };
    case 'FETCH_FAIL':
      return { ...state, loading: false, error: action.payload };
    case 'DELETE_REQUEST':
      return { ...state, loadingDelete: true };
    case 'DELETE_SUCCESS':
      return { ...state, loadingDelete: false, successDelete: true };
    case 'DELETE_FAIL':
      return { ...state, loadingDelete: false };
    case 'DELETE_RESET':
      return { ...state, loadingDelete: false, successDelete: false };
    default:
      state;
  }
}


function AdminDash() {
  const { state } = useContext(Store);
  const router = useRouter;
  const [
    {
      loading,
      error,
      notes,
      currentPage,
      pageCount,
      totalCount,
      successDelete,
      loadingDelete,
    },
    dispatch,
  ] = useReducer(reducer, {
    loading: true,
    notes: [],
    currentPage: 1, 
    pageCount: null,
    totalCount: null,
    error: '',
  });

  useEffect(() => {
    const fetchData = async () => {
      try {
        dispatch({ type: 'FETCH_REQUEST', payload: currentPage });
        const { data } = await axios.get(
          `/api/admin/notes/?page=${currentPage}`, {
        headers: { authorization: `Bearer ${userInfo.token}` }, });
        dispatch({ type: 'FETCH_SUCCESS', payload: data.notes });
        dispatch({ type: 'NUMBER_OF_PAGES', payload: data.totalPages });
        dispatch({ type: 'CURRENT_PAGE', payload: data.currentPage });
      } catch (err) {
        dispatch({ type: 'FETCH_FAIL', payload: getError(err) });
      }
    };
    if (successDelete) {
      dispatch({ type: 'DELETE_RESET' });
    } else {
      fetchData();
    }
  }, [successDelete]);

  const handleChangePage = async () => {
    dispatch({ type: 'FETCH_REQUEST', payload: currentPage });
    const { data } = await axios.get(
      `/api/admin/notes/?page=${currentPage}`
    );
    dispatch({ type: 'FETCH_SUCCESS', payload: data.notes });
  };

  const { enqueueSnackbar } = useSnackbar();

  const deleteHandler = async (userId) => {
    if (!window.confirm('Are you sure?')) {
      return;
    }
    try {
      dispatch({ type: 'DELETE_REQUEST' });
      await axios.delete(`/api/admin/users/${userId}`, {
        headers: { authorization: `Bearer ${userInfo.token}` },
      });
      dispatch({ type: 'DELETE_SUCCESS' });
      enqueueSnackbar('User deleted successfully', { variant: 'success' });
    } catch (err) {
      dispatch({ type: 'DELETE_FAIL' });
      enqueueSnackbar(getError(err), { variant: 'error' });
    }
  };
  
  
   return (
    <Layout title="Admin Dashboard">
    <Grid item md={10} xs={12}>
        <ListItem>
          <TableContainer>
            <Table>
              <TableHead>
                <TableRow>
                  <TableCell>{..data}</TableCell>
                </TableRow>
                             </TableBody>
            </Table>
          </TableContainer>
        </ListItem>
        <Pagination
        sx={classes.section}
        defaultPage={parseInt(currentPage || '1')}
        count={pageCount}
        onChange={handleChangePage}
      ></Pagination>
      </Grid>
     </Layout>);}
     
export default dynamic(() => Promise.resolve(AdminDash), { ssr: false });

    
    

匆忙实施 table 分页。 在 tables 上使用 TablePagination 和相应的数据映射,如以下示例

<TableContainer>
            <Table>
              <TableHead>
                <TableRow>
                  <TableCell>[...Headers...]</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {/* {listings.map((listing) => ( */}
                {notes
                  .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                  .map((note) => (
                    <TableRow key={listing.index}>
                      <TableCell>{listing.index}</TableCell>
                      <TableCell align="right">{[...note.data...}</TableCell>
                    </TableRow>
                  ))}
              </TableBody>
              <TableFooter>
                <TableRow>
                  <TablePagination
                    rowsPerPageOptions={[5, 10, 20]}
                    component="grid"
                    count={note.length}
                    rowsPerPage={rowsPerPage}
                    page={page}
                    onPageChange={handleChangePage}
                    onRowsPerPageChange={handleChangeRowsPerPage}
                  />
                </TableRow>
              </TableFooter>
            </Table>
          </TableContainer>