我需要做什么才能在我的渲染器中访问 `currentPage` 和 `setCurrentPage`

What do I need to do to access `currentPage` and `setCurrentPage` inside my render

我正在尝试按照 this 网络文章来实现分页。

import React, { useState, useMemo } from "react";
import Config from 'config';
import { formatter } from '../common.js'
import { format } from 'date-fns';
import Pagination from '../Pagination';
import "./Order.css";

let PageSize = 25;

class Portal extends React.Component {
    constructor() {
        super();
        this.state = {
            name: 'React',
            apiData: [],
        };
    }

    async componentDidMount() {        
        console.log('app mounted');

        const tokenString = sessionStorage.getItem("token");
        const token = JSON.parse(tokenString);

        let headers = new Headers({
            "Accept": "application/json",
            "Content-Type": "application/json",
            'Authorization': 'Bearer ' + token.token
        });
        
        const response = await fetch(Config.apiUrl + `/api/Orders/GetAllInvoices`, {
            method: "GET",
            headers: headers
        });
        const json = await response.json();
        console.log(json);
        this.setState({ orderList: json });
    }

    render() {
        const orders = this.state.orderList;
        const [currentPage, setCurrentPage] = useState(1);  <<== Error here

        const currentTableData = useMemo(() => {
            const firstPageIndex = (currentPage - 1) * PageSize;
            const lastPageIndex = firstPageIndex + PageSize;
            return orders.slice(firstPageIndex, lastPageIndex);
        }, [currentPage]);

        return (
            <div>
                <h2>Portal</h2>
                <br />
                <h3>Past Orders</h3>
                <table className="table table-striped table-bordered">
                    <thead>
                        <tr>
                            <th className="number">Invoice Number</th>
                            <th className="date">Invoice Date</th>
                            <th className="amount">Amount</th>
                        </tr>
                    </thead>
                    <tbody>
                        {currentTableData && currentTableData.map(order =>
                            <tr key={order.sopnumbe}>
                                <td>{order.sopnumbe}</td>
                                <td>{format(Date.parse(order.docdate), 'MM/dd/yyyy')}</td>
                                <td>{formatter.format(order.docamnt)}</td>
                            </tr>
                        )}
                    </tbody>
                </table>
                <Pagination
                    className="pagination-bar"
                    currentPage={currentPage}
                    totalCount={orders.length}
                    pageSize={PageSize}
                    onPageChange={page => setCurrentPage(page)}
                />
            </div>
        );
    }
}
export default Portal;

因为它是一个 class 组件,所以我在 'Invalid hook call' 尝试 useHook 内部 class 组件时遇到错误 here

我试过将它移到外部函数中并在我的渲染中调用 foo()

import React, { useState, useMemo } from "react";
import Config from 'config';
import { formatter } from '../common.js'
import { format } from 'date-fns';
import Pagination from '../Pagination';
import "./Order.css";

let PageSize = 25;

function foo() {
    const [currentPage, setCurrentPage] = useState(1);
}
...

但是现在我需要做什么才能在渲染函数中访问 currentPagesetCurrentPage,添加 this. 或将 const [currentPage, setCurrentPage] = useState(1) 行移动到 componentDidMount?

挂钩应该用功能组件而不是 class 组件编写。

写同样的逻辑。对于 class 个组件,您需要像在构造函数中所做的那样声明状态并使用生命周期方法

class Portal extends React.Component {
    constructor() {
        super();
        this.state = {
            name: 'React',
            apiData: [],
            orderList: [],
            currentPage: 1,
            currentTableData: [],
        };
    }

    async componentDidMount() {        
        console.log('app mounted');

        const tokenString = sessionStorage.getItem("token");
        const token = JSON.parse(tokenString);

        let headers = new Headers({
            "Accept": "application/json",
            "Content-Type": "application/json",
            'Authorization': 'Bearer ' + token.token
        });
        
        const response = await fetch(Config.apiUrl + `/api/Orders/GetAllInvoices`, {
            method: "GET",
            headers: headers
        });
        const json = await response.json();
        console.log(json);
        this.setState({ orderList: json });
    }

    componentDidUpdate(_, prevState) {
        if(prevState.currentPage !== this.state.currentPage) {
            const firstPageIndex = (currentPage - 1) * PageSize;
            const lastPageIndex = firstPageIndex + PageSize;
            this.setState({currentTableData: orders.slice(firstPageIndex, lastPageIndex)});
       }
    }
    render() {
        const orders = this.state.orderList;
        const currentTableData = this.state.currentTableData;
        return (
            <div>
                <h2>Portal</h2>
                <br />
                <h3>Past Orders</h3>
                <table className="table table-striped table-bordered">
                    <thead>
                        <tr>
                            <th className="number">Invoice Number</th>
                            <th className="date">Invoice Date</th>
                            <th className="amount">Amount</th>
                        </tr>
                    </thead>
                    <tbody>
                        {currentTableData && currentTableData.map(order =>
                            <tr key={order.sopnumbe}>
                                <td>{order.sopnumbe}</td>
                                <td>{format(Date.parse(order.docdate), 'MM/dd/yyyy')}</td>
                                <td>{formatter.format(order.docamnt)}</td>
                            </tr>
                        )}
                    </tbody>
                </table>
                <Pagination
                    className="pagination-bar"
                    currentPage={currentPage}
                    totalCount={orders.length}
                    pageSize={PageSize}
                    onPageChange={page => this.setState({currentPage: page})}
                />
            </div>
        );
    }
}
export default Portal;