cdcasey.dev

gatsbyhireactsite info

"More" Button for Gatsby

On the site for my podcast, One to Grow On, we used to have pagination links.

links that point to older and newer episodes

This was fine to get the site up and running. Before long, however, I felt the mechanism that pagniation links provided was too tedious and I needed to replace them with something else. I have almost never had a good experience with infinite scroll, so that was out as an option. I had seen a few "More" buttons on other websites and decided that was the way to go. Here is the code from my index.js file:

1// edges comes off of the props and is all posts filtered by category
2const MAX_POSTS = edges.length
3
4const setPostNum = () => {
5 setPostLimit((prevPostLimit) => {
6 let newPostLimit = prevPostLimit + 6
7 newPostLimit = newPostLimit >= MAX_POSTS ? MAX_POSTS : newPostLimit
8 return newPostLimit
9 })
10}
11
12const [postLimit, setPostLimit] = React.useState(9)
13
14// previewlinks is the final list of posts previews to display
15const shownPosts = previewLinks.slice(0, postLimit)

Then there's a button that triggers setPostNum to increase the limit shown:

1// MoreButton is a styled component created with Emotion
2<MoreButton type="button" onClick={setPostNum} disabled={postLimit >= MAX_POSTS}>
3 {postLimit >= MAX_POSTS ? <span>That&rsquo;s it!</span> : 'More...'}
4</MoreButton>

Thats it for the basic functionality. In the TODO column I put changing the number of posts displayed based on the screen width.

I did take one more step. I didn't think the entire list of post previews should be regenerated each time a user hit the more button.

1// PreviewLink is a styled component created with Emotion
2const previewLinks = React.useMemo(() => {
3 return edges.map(({ node }) => {
4 const bgUrl = node.featuredImage
5 ? node.featuredImage.node.localFile?.childImageSharp.fixed.src
6 : ''
7 return (
8 <PreviewLink
9 key={node.id}
10 uri={node.uri}
11 slug={node.slug}
12 title={node.title}
13 date={node.date}
14 excerpt={node.excerpt}
15 bgUrl={bgUrl}
16 />
17 )
18 })
19}, [edges])

This may be, as the kids say these days, a premature optimization. useMemo is supposed to be used for expensive calculations, and a simple map hardly seems expensive. Nevertheless, reducing unnecessary re-renders always seems like a good thing.

prev: Adding Styling