Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 方法在React中更新状态后仍无法获取正确的useState值_Javascript_Reactjs_Pagination_Use State - Fatal编程技术网

Javascript 方法在React中更新状态后仍无法获取正确的useState值

Javascript 方法在React中更新状态后仍无法获取正确的useState值,javascript,reactjs,pagination,use-state,Javascript,Reactjs,Pagination,Use State,我在一个网站上工作,我试图显示分页的学生信息。例如,我有12名学生,我有分页项目1-4,因为我一次显示3名学生 调用更新分页函数时遇到问题。此方法中的计数器始终为0,尽管我正确地递增了它。任何想法或建议都将不胜感激 import React, {useState, useEffect} from 'react'; function App() { let students = [ {'name': 'Harry'}, {'name': 'Hermoine'}, {'

我在一个网站上工作,我试图显示分页的学生信息。例如,我有12名学生,我有分页项目1-4,因为我一次显示3名学生

调用更新分页函数时遇到问题。此方法中的计数器始终为0,尽管我正确地递增了它。任何想法或建议都将不胜感激

import React, {useState, useEffect} from 'react';

function App() {
  let students = [
    {'name': 'Harry'},
    {'name': 'Hermoine'},
    {'name': 'Ron'},
    {'name': 'Ginny'},
    {'name': 'Snape'},
    {'name': 'Bellatrix'},
    {'name': 'Albus'},
    {'name': 'Dudley'},
    {'name': 'Petunia'},
    {'name': 'Hagrid'},
    {'name': 'Lee'},
    {'name': 'James'}
  ];

 let [loaded, setLoaded] = useState(false);
 let [pagination, setPagination] = useState([]);
 let [limit, setLimit] = useState(3); // how many students are visible at a time
 let [pages, setPages] = useState(Math.round(students.length/limit)); // amount of pages based on total students
 let [currentPage, setCurrentPage] = useState(1); // the current page
 let [pageCount, setPageCount] = useState(0); // counter used to increment/decrement pages in view

function updatePagination() {
 let tmpArray = [];

 for(let i = pageCount; i < pages; i ++){
  tmpArray.push(i+1);
 }

 // 1-3, 4-6 etc...
 setPagination(tmpArray.slice(pageCount, pageCount + limit)); // this pageCount is always 0 despite me setting it on handleNext method
}

function handleNext(){
 setCurrentPage(currentPage + 1);

 if(pageCount + limit === currentPage){
  if(currentPage <= pages){
    setPageCount(pageCount + limit);
  }
 }

 updatePagination();
}

useEffect(() => {
 updatePagination();
 setLoaded(true);
}, []);

return (
 <main className={styles.app}>
  <div className={styles.student}>
    <h1>Three student cards</h1>
  </div>

  <ol className={styles.pagination}>
    <div className={styles.paginationContainer}>
      <button className={currentPage === 0 ? styles.prev + ' ' + styles.disabled : styles.prev}>prev</button>

      {loaded && pagination.map((item, index) => {
        return (
          <li key={index} className={styles.paginationItem}>
            <button className={currentPage === item ? styles.active : null}>{item}</button>
          </li>
        )
      })}

      <button onClick={() => {
        handleNext()
      }} className={currentPage === pages ? styles.next + ' ' + styles.disabled : styles.next}>next</button>
    </div>
  </ol>

  {loaded &&
  <div className={styles.info}>
    <p>Page Count: {pageCount}</p>
    <p>Current Page: {currentPage}</p>
    <p>Limit: {limit}</p>
    <p>Pages: {pages}</p>
    <p>Total Students: {students.length}</p>
    <p>Pagination: {pagination}</p>
  </div>
  }
</main>
);
}

export default App;
import React,{useState,useffect}来自“React”;
函数App(){
让学生=[
{'name':'Harry'},
{'name':'Hermoine'},
{'name':'Ron'},
{'name':'Ginny'},
{'name':'Snape'},
{'name':'Bellatrix'},
{'name':'Albus'},
{'name':'Dudley'},
{'name':'penunia'},
{'name':'Hagrid'},
{'name':'Lee'},
{'name':'James'}
];
let[loaded,setLoaded]=useState(false);
让[pagination,setPagination]=useState([]);
让[limit,setLimit]=useState(3);//一次可以看到多少学生
let[pages,setPages]=useState(Math.round(students.length/limit));//基于学生总数的页数
让[currentPage,setCurrentPage]=useState(1);//当前页
让[pageCount,setPageCount]=useState(0);//用于递增/递减视图中页面的计数器
函数updatePagination(){
设tmpArray=[];
for(设i=pageCount;i{
返回(
  • {item}
  • ) })} { handleNext() }}className={currentPage===pages?styles.next+''+styles.disabled:styles.next}>next {加载&& 页面计数:{pageCount}

    当前页:{currentPage}

    限制:{Limit}

    页面:{Pages}

    学生总数:{Students.length}

    分页:{Pagination}

    } ); } 导出默认应用程序;
    以下是代码中的问题:

    • handleNext()
      函数中,您在调用
      setCurrentPage(…)
      函数后立即使用
      currentPage
      ,但状态是异步更新的。因此
      currentPage
      将是旧值而不是更新值

    • 另一个问题是,如果用户单击
      next
      按钮三次,则条件
      pageCount+limit===currentPage
      将为
      true
      pageCount
      将设置为
      pageCount+limit
      ,即3。这意味着(设i=pageCount;i只执行一次。因此
      tmpArray
      只包含一个元素,即4

    • 此外,由于调用
      handleNext()
      函数会根据其先前的值更新
      currentPage
      ,因此应通过将函数传递给
      setCurrentPage()
      函数来更新状态

      setCurrentPage((page) => page + 1);
      
      与上一页类似:

      setCurrentPage((page) => page - 1);
      
      这将确保状态正确更新

    编辑: 之前不清楚您为什么要使用
    pageCount
    ,但您在评论中发布的演示清楚地表明了您想要实现的目标

    您在问题中提到的问题是
    pageCount
    的值始终为零。查看您的代码,我认为您根本不需要
    pageCount

    要实现所需的功能,您需要采取以下步骤:

  • 要填充
    分页
    数组,您可以使用
    useffect
    钩子,每当
    students
    数组或
    limit
    更改时执行该钩子

    useEffect(() => {
       // set pagination
       let arr = new Array(Math.ceil(students.length / limit))
          .fill()
          .map((_, idx) => idx + 1);
    
       setPagination(arr);
       setLoaded(true);
    
    }, [students, limit]);
    
  • 要一次显示有限数量的学生,请创建一个函数,根据
    currentPage
    limit
    students
    数组进行切片

    const getPaginatedStudents = () => {
       const startIndex = currentPage * limit - limit;
       const endIndex = startIndex + limit;
    
       return students.slice(startIndex, endIndex);
    };
    
  • 要显示与
    限制相等的有限页数
    ,您不需要
    页面计数
    。您可以创建一个函数,根据
    当前页面
    限制
    分页
    数组进行切片。此函数类似于在步骤2中创建的函数,但区别在于
    如何启动t已计算出索引

    const getPaginationGroup = () => {
       let start = Math.floor((currentPage - 1) / limit) * limit;
       let end = start + limit;
    
       return pagination.slice(start, end);
    };
    
  • 创建将更改当前页面的函数

    function goToNextPage() {
       setCurrentPage((page) => page + 1);
    }
    
    function goToPreviousPage() {
       setCurrentPage((page) => page - 1);
    }
    
    function changePage(event) {
       const pageNumber = Number(event.target.textContent);
       setCurrentPage(pageNumber);
    }
    
  • 这就是获得所需功能所需的全部

    演示 以下代码段显示了一个示例:

    const studentsData=[
    {名字:“哈里”},
    {姓名:“赫敏”},
    {name:“Ron”},
    {名字:“金妮”},
    {name:“Snape”},
    {name:“Bellatrix”},
    {name:“Albus”},
    {姓名:“达德利”},
    {名称:“佩妮”},
    {名字:“海格”},
    {姓名:“李”},
    {姓名:“詹姆斯”},
    {名字:“莉莉”},
    {名称:“雷姆斯”},
    {name:“伏地魔”},
    {名称:“多比”},
    {姓名:“卢修斯”},
    {名称:“天狼星”}
    ];
    函数学生({name}){
    返回(
    {name}
    );
    }
    函数App(){
    让[学生]=反应。使用状态(学生数据);
    让[pagination,setPagination]=React.useState([]);
    let[loaded,setLoaded]=React.useState(false);
    let[limit]=React.useState(3);
    让[pages]=React.useState(Math.round(students.length/limit));
    让[currentPage,setCurrentPage]=React.useState(1);
    函数goToNextPage(){
    setCurrentPage((第页)=>第+1页);
    }
    函数goToPreviousPage(){
    setCurrentPage((第页)=>第1页);
    }
    函数更改页(事件){
    常量页码=编号(event.target