我有这个代码的问题
如果我将整个pagination
对象传递给useEffect()
函数的第二个参数,fetchData()
则将连续调用。如果我只通过pagination.current_page
它,它将仅调用一次,但是当我pagination
在navigatePage()
函数中看到新设置的值时,尽管发生了变化,useEffect()
但不调用。fetchData()
pagination
如何解决这个问题。非常感谢你!
此外,我不希望useEffect()
在首次安装组件时使用use 调用,因为items
它是从props接收到的(由服务器获取,这是nextjs项目)。
import React, {useEffect, useState} from 'react';
import Filter from "../Filter/Filter";
import AdsListingItem from "../AdsListingItem/AdsListingItem";
import {Pagination} from "antd-mobile";
import styles from './AdsListing.module.css';
import axios from 'axios';
const locale = {
prevText: 'Trang trước',
nextText: 'Trang sau'
};
const AdsListing = ({items, meta}) => {
const [data, setData] = useState(items);
const [pagination, setPagination] = useState(meta);
const {last_page, current_page} = pagination;
const fetchData = async (params = {}) => {
axios.get('/ads', {...params})
.then(({data}) => {
setData(data.data);
setPagination(data.meta);
})
.catch(error => console.log(error))
};
useEffect( () => {
fetchData({page: pagination.current_page});
}, [pagination.current_page]);
const navigatePage = (pager) => {
const newPagination = pagination;
newPagination.current_page = pager;
setPagination(newPagination);
};
return (
<>
<Filter/>
<div className="row no-gutters">
<div className="col-md-8">
<div>
{data.map(item => (
<AdsListingItem key={item.id} item={item}/>
))}
</div>
<div className={styles.pagination__container}>
<Pagination onChange={navigatePage} total={last_page} current={current_page} locale={locale}/>
</div>
</div>
<div className="col-md-4" style={{padding: '15px'}}>
<img style={{width: '100%'}} src="https://tpc.googlesyndication.com/simgad/10559698493288182074"
alt="ads"/>
</div>
</div>
</>
)
};
export default AdsListing;
问题是您没有返回新的对象引用。您保存对最后一个状态对象的引用,对它的属性进行突变,然后再次保存。
const navigatePage = (pager) => {
const newPagination = pagination; // copy ref pointing to pagination
newPagination.current_page = pager; // mutate property on ref
setPagination(newPagination); // save ref still pointing to pagination
};
在这种情况下,在内存中的位置是 pagination
保持不变。您应该将所有pagination
属性复制到一个新对象中。
const navigatePage = (pager) => {
const newPagination = {...pagination}; // shallow copy into new object
newPagination.current_page = pager;
setPagination(newPagination); // save new object
};
要更进一步,您确实应该进行功能更新,以便正确地排队更新。setPagination
在单个渲染周期中多次调用的情况下。
const navigatePage = (pager) => {
setPagination(prevPagination => {
const newPagination = {...prevPagination};
newPagination.current_page = pager;
});
};
在分页排队的情况下,更新可能不是问题(最后一个当前页面集将赢得下一次渲染大战),但是如果任何状态更新实际上取决于先前的值,那么一定使用功能性更新模式,
谢谢你,德鲁 我已经接受了这个答案。