I am trying to create a functionality where if a user clicks on a LOAD MORE button, it returns more data.
I already have some code done but every time I click on the LOAD MORE button, it removes the first 12 items and sets the new 12 items, but I don’t want that, I want to keep the 12 old tems, It is just a regular load more functionality.
const Comp = ({ data }) => {
const postsPerPage = 12
const [postsToShow, setPostsToShow] = useState([])
const [next, setNext] = useState(postsPerPage)
let arrayForHoldingPosts = []
const loopWithSlice = (start, end) => {
const slicedPosts = data.products.slice(start, end)
arrayForHoldingPosts = [...arrayForHoldingPosts, ...slicedPosts]
setPostsToShow(arrayForHoldingPosts)
}
useEffect(() => {
loopWithSlice(0, postsPerPage)
}, [])
const handleShowMorePosts = () => {
loopWithSlice(next, next + postsPerPage)
setNext(next + postsPerPage)
}
return (
<div>
{postsToShow.map(p => <div>...</div>)}
<button onClick={handleShowMorePosts}>Load more</button>
</div>
)
}
Besides that, I need to turn this into a hook which I am going to using across the whole application.
What am I missing?
Any ideas?
Advertisement
Answer
You do not need an array arrayForHoldingPosts instead just use
setPostsToShow( [...postsToShow, ...slicedPosts]);
arrayForHoldingPosts is becoming empty array after every renders so old data is lost.
Hook example
const useLoadMore = (data, postsPerPage = 2) => {
const [postsToShow, setPostsToShow] = useState([]);
const [next, setNext] = useState(postsPerPage);
const loopWithSlice = (start, end) => {
const slicedPosts = data.slice(start, end);
setPostsToShow( [...postsToShow, ...slicedPosts]);
};
useEffect(() => {
loopWithSlice(0, postsPerPage);
}, []);
const handleShowMorePosts = () => {
loopWithSlice(next, next + postsPerPage);
setNext(next + postsPerPage);
};
return { handleShowMorePosts, postsToShow }
}
const App = ({data}) => {
const {handleShowMorePosts, postsToShow } = useLoadMore(data)
return (
<div>
{postsToShow.map((p) => (
<div>...</div>
))}
<button onClick={handleShowMorePosts}>Load more</button>
</div>
);
};