【问题标题】:What do I need to do to access `currentPage` and `setCurrentPage` inside my render我需要做什么才能在我的渲染中访问`currentPage`和`setCurrentPage`
【发布时间】:2021-08-09 02:17:13
【问题描述】:

我正在尝试关注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;

由于它是一个类组件,我在尝试 useHook 时收到错误“无效的钩子调用”,如提到的 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 中?

【问题讨论】:

  • 类组件不支持钩子。如果您想使用钩子(useStateuseEffect..),您可以从编写新代码作为带有钩子的功能组件开始。您可以阅读有关 Hooks-FAQ 的更多信息here

标签: javascript reactjs pagination


【解决方案1】:

Hooks 是写在函数式组件中,而不是类组件中。

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

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;

【讨论】:

  • 我对你进行了更改,但我在totalCount={orders.length} 线上收到了错误orders is undefined
  • 在构造函数中初始化orderList状态为空数组
  • 现在我在 Pagination.js 第 28 行收到错误 TypeError: paginationRange is undefined。顺便说一句,感谢您提供的精彩网络文章。
  • 我们将不得不处理 totalCount 为零的情况,我认为文章中缺少这一点
  • 我将第 28 行更改为 if (currentPage === 0 || typeof paginationRange === 'undefined' || paginationRange.length &lt; 2)。我现在没有收到任何错误,但我也没有收到任何物品。
猜你喜欢
  • 1970-01-01
  • 2010-09-15
  • 2022-11-05
  • 1970-01-01
  • 1970-01-01
  • 2010-12-31
  • 2012-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多