为什么分页不起作用?以及如何解决?

我正在请求本地服务器。服务器返回我响应:

{"total":7,
"perPage":3,
"page":1,
"lastPage":3,
 "data":[
     {"id":1,"title":"animals","created_at":"/...","updated_at":"/..."},
     {"id":2,"title":"space","created_at":"/...","updated_at":"/..."},
     {"id":3,"title":"sport","created_at":"/...","updated_at":"/..."}
]}
  • data - it list of category. And I display my list in the form of a table.

  • total, perPage, page, lastPage - it query param which I will insert into URL to filter my list.

  • page - the current page number. If in field page would be number two, then it would be in data the other three objects. That is, there would be in data other categories, with other title and id.

I have task:
- make pagination with three buttons.Because I have three page"lastPage":3.

以及我的实现方式(我在某些地方加了注释): 文件Home.js:

const Home = () => {

     const [value, setValue] = useState({
         listCategory: [],                   //  here I put my list of categories
         currentPage: 1                      // here I set initial page
     });

      useEffect(() => {
         fetchData();
      },[]);

      async function fetchData() {
         try {
            const res = await apiCategory('api/categories', { //apiCategory it function I'll write it below    
              method:'GET'
            });
              console.log(res);
              setValue({
                  listCategory:res.data,       // I put the received data in an empty array to display the category list on the page
                  currentPage:res.page          // set page which is default in response from server, now it-("page":1)
              });
            } catch(e) { 
                console.error(e);
            } 
    };

     const changePage = (argPage) => {
         setValue({
             currentPage: argPage               // change page depending on which button was pressed
         });
     }

      return (
        <div>
            <Search/>
            <Table dataAttribute = {value.listCategory} />    // dispaly category list

            {Object.keys(value.currentPage).map((item, index) => (
               <button key={item} onClick={() => changePage(index)}>{item}</button>
            ))}         // dispaly button and attach method changePage

        </div>
    )}

有函数apiCategory(apiCategory.js):

export const apiCategory = async (url, args) => { 
const getToken = localStorage.getItem('myToken');
const valuePage = value.currentPage;               //currentPage- props of my state in useState
  const response = await fetch(`${apiUrl}${url}?page=${valuePage}`, {  //I substitute in URL value from valuePage that implement pagination
   ...args,
    headers: {
      "Content-type": "application/json; charset=UTF-8 ",
      "Authorization": `Bearer ${getToken}`,
      "Accept": 'application/json',
      ...args.headers,  
    },
  });

 return response.json();      
}

But I did not have buttons that switch pages(pagination). Only category list displays(screenshot): https://i.piccy.info/i9/0b04d1777b6769e3a4dcb500faa3554a/1587741736/24398/1372209/Screenshot_1.png

甚至他们都不会改变自己的状况。我不知道...

另外在函数apiCategory中我有错误

未定义“值” no-undef

in this line:
const valuePage = value.currentPage;

我应该在代码中进行哪些更改,以便出现按钮和分页功能?

我还将写一个文件Table.js:

export default ({dataAttribute}) => (
  <table className="table">
    <thead className="table-head">
      <tr >
        <th>id</th>
        <th>title</th>
        <th>created_at</th>
        <th>updated_at</th>
      </tr>
    </thead>
    <tbody>
      {dataAttribute.map(item => (
        <tr key={item.id}>
          <td>{item.id}</td>
          <td>{item.title}</td>
          <td>{item.created_at}</td>
          <td>{item.updated_at}</td>
        </tr>
      ))}
    </tbody>
  </table>
);

评论
  • Tate
    Tate 回复

    You need to pass value into the apiCategory function, otherwise it is undefined. If you want fetchData to fire every time the next page is selected then it needs to be a dependency in useEffect.

    Home.js

    useEffect(() => {
      async function fetchData(currentPage) {
        try {
          const res = await apiCategory('api/categories', {
            method:'GET'
          }, currentPage);
          console.log(res);
          setValue({
            listCategory:res.data
            currentPage:res.page
          });
        } catch(e) { 
          console.error(e);
        } 
      };
      fetchData(value.currentPage);
    },[value.currentPage]);
    

    apCategory.js

    export const apiCategory = async (url, args, valuePage) => { 
    ...
    // remove the local valuePage line
    

    Also note that you are removing the listCategory property in value every time changePage is called. To preseve the previous values, you need to change it to this:

    const changePage = (argPage) => {
       setValue((prev) => {
         return {
           ...prev,
           currentPage: argPage 
         }
       });
     }
    

    作为回报,您没有正确引用数据结构。

    {value.listCategory.map((item, index) => (
      <button 
        key={'listCategory_'+index} 
        onClick={() => changePage(index)}
      >
        {item}
      </button>
    ))}