【问题标题】:How to change pagination variables in react如何在反应中更改分页变量
【发布时间】:2022-01-23 04:01:44
【问题描述】:

我正在构建分页。我仍在使用 API 来根据分页获取帖子,但目前我遇到了状态问题。

在我的主文件(帖子所在的位置)中,我的代码如下所示:

// Import modules
import React from "react";
import axios from "axios";
import url from "url";

// Import components
import { Snippet } from "../Snippet";
import { CreatePost } from "./CreatePost";
import { Pagination } from "./Pagination";

// Import styles
import "./css/Content.css";

// Axios Init
const api = axios.create({
    baseURL: `http://localhost:5000/api/`,
});

export class Content extends React.Component {
    state = {
        collections: [
            { title: "ReactJS", color: "red" },
            { title: "HTML", color: "cyan" },
            { title: "CSS", color: "pink" },
        ],
        snippets: [],
        limitSnippets: 3,
        page: 0,
    };

    constructor(props) {
        super(props);
    }

    componentDidMount() {
        this.getSnippets();
    }

    getSnippets = async () => {
        try {
            let data = await api
                .get(
                    `/snippets/fetchAll?limitSnippets=${this.state.limitSnippets}&page=${this.state.page}`,
                    {
                        body: {
                            limitSnippets: 3,
                            page: 1,
                        },
                    }
                )
                .then(({ data }) => data);
            this.setState({ snippets: data });
        } catch (error) {
            console.log(error);
        }
    };

    updatePagination = (page) => {
        this.state.page = page;
        console.log(this.state.page);
    };

    render() {
        return (
            <div className="content">
                <h1 className="content-header">Snippets</h1>
                <CreatePost contentUpdater={this.getSnippets} />
                <Pagination updatePagination={this.updatePagination} />
                <div className="w-layout-grid grid">
                    {this.state.snippets.map((snippet, i) => {
                        return (
                            <Snippet
                                key={i}
                                title={snippet.title}
                                code={snippet.code}
                                updatedDate={snippet.updatedDate}
                                createdDate={snippet.createdDate}
                                language={snippet.language}
                                creator={snippet.creator}
                                collections={snippet.collections}
                            />
                        );
                    })}
                </div>
                <Pagination />
            </div>
        );
    }
}
export default Content;

在分页文件中,我的代码如下所示:

export const Pagination = (props) => {
    // States
    const [page, setPage] = useState(0);
    // Axios Init
    const api = axios.create({
        baseURL: `http://localhost:5000/api/`,
    });

    const handleLeft = (event) => {
        event.preventDefault();
        if (page > 0) {
            setPage(page - 1);
            props.updatePagination(page);
        } else {
            console.log("handleLeft(): page not > 0");
        }
        //props.updatePagination(page);
        //}
    };

    const handleRight = (event) => {
        event.preventDefault();
        // page < fetchAllPages
        setPage(page + 1);
        props.updatePagination(page);
    };

    /*useEffect(() => {
        props.updatePagination(page);
    }, [page]);
*/
    return (
        <div className="paginate-div">
            <div className="paginate-next">
                <div className="paginate-next-icon" onClick={handleLeft}>
                    <i className="fas fa-caret-left"></i>
                </div>
            </div>
            <a href="#" className="paginate-button first w-inline-block">
                <div className="paginate-text">1</div>
            </a>
            <a href="#" className="paginate-button w-inline-block">
                <div className="paginate-text">2</div>
            </a>
            <a href="#" className="paginate-button w-inline-block">
                <div className="paginate-text">3</div>
            </a>
            <a href="#" className="paginate-button w-inline-block">
                <div className="paginate-text">4</div>
            </a>
            <a href="#" className="paginate-button w-inline-block">
                <div className="paginate-text">5</div>
            </a>
            <a href="#" className="paginate-button w-inline-block">
                <div className="paginate-text">6</div>
            </a>
            <a href="#" className="paginate-button last w-inline-block">
                <div className="paginate-text">...</div>
            </a>
            <div className="paginate-next" onClick={handleRight}>
                <div className="paginate-next-icon">
                    <i className="fas fa-caret-right"></i>
                </div>
            </div>
        </div>
    );
};

我有我的分页组件,它传递了一个 prop,它是 updatePagination() 的函数。分页组件具有左右键切换分页功能,点击后主文件更新分页。

我遇到的问题(对不起,如果我的措辞让我感到困惑) 默认页面为 0(基本上是第 1 页)。 疯狂的事情是当我按下右(handleRight 在提交时调用)时,它停留在第 0 页,然后如果我再次单击它,它会转到 1,然后如果我按下左按钮(其中在提交时调用handleLeft),当它在第1页时,它会以某种方式上升到2,但是如果我再次点击它,它会回到1,然后如果我再次点击它会回到0。

为什么会出现这个奇怪的问题?

【问题讨论】:

    标签: javascript node.js reactjs express mongoose


    【解决方案1】:

    问题是在 updatePagination() 中使用了 page 的旧值,我通过不在同一个地方运行 updatePagination(page) 解决了这个问题,我使用了 useEffect(),并检查了对 {page} 的更改,并在那里运行 updatePagination。

    useEffect(() => {
        props.updatePagination(page);
    }, [page]);
    

    handleLeft、handleRight 函数更改为如下所示:

    const handleLeft = (event) => {
            event.preventDefault();
            let newPage = page - 1;
            if (page > 0) {
                setPage(newPage);
            } else {
                console.log("handleLeft(): page not > 0");
            }
    
            //}
        };
    

    注意” 在 cmets 部分,有人提出我不应该将页码存储在两个地方,而是将它们存储在一个地方并将其作为道具传递。 我目前没有尝试这样做,但我计划很快这样做。但就目前而言,这是该场景的最佳答案。

    【讨论】:

      【解决方案2】:

      setPage 是异步的,所以当你将setPage 递减然后立即调用props.updatePage 时,props.updatePage 正在接收page 的旧值。您可以阅读有关此常见问题的所有内容here

      const handleRight = (event) => {
              event.preventDefault();
              // Hey React, set page to page + 1 and rerender the component
              setPage(page + 1);
              // But before you do that, call props.updatePagination on the old value
              props.updatePagination(page);
          };
      

      不过,您应该问自己,为什么您甚至要存储两个有状态的 page 值(一个在父组件中,一个在子组件中)。 Content 组件不能跟踪您的页面状态(就像它已经做到的那样)并将其作为道具传递下来,从而摆脱您对子组件中页面状态的需求?这称为Lifting State Up,它是 React 中的一个基本概念,它激励您使用尽可能少的状态来避免这种不同步。此外,从您共享的代码中,Pagination 组件只显示页码 - 为什么它甚至需要有状态?

      【讨论】:

      • 这是一个非常非常好的观点。我是新手,所以我还在学习所有这些概念......但无论如何,在我将页面状态转换为单个组件之前,你能告诉我如何在调用 updatePagination() 之前确保页面不是旧值吗?只是想了解我如何做到这一点,即使我要更改代码以适应您的想法
      • 我学会了如何使用 useEffect() 并且有了它,它起作用了!感谢您的帮助。
      猜你喜欢
      • 2020-06-19
      • 2022-08-18
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 2021-03-16
      • 2015-10-05
      • 1970-01-01
      • 2021-11-14
      相关资源
      最近更新 更多