Build Pagination in React

Hello everyone, I’m looking for a way to create Pagination in React.
But I also use the following:
ssr
fast render
What do you think is the best solution?

Pagination is just telling the database where to start and where to end. You just take the amount per page and divide by your total to get total pages. Then you can itereate and create a link list. It’s literally just floated divs or some people use ul tags down to you

Each page you need to pass a variable for the page number and have the subscription get that page by setting the limit for the total and of course the skip - the place to start from.

For example:

db.history.find({ customerId: 7000000 })
            .sort({ date: 1 })
            .skip(1000)
            .limit(1000)

Here we get 1000 chronologically ordered records, starting on what is page 2 (from the 1001st record) (for uncached data only) the problem with this is the database has to load 2000 records in order to skip the first 1000. This isn’t a problem on smaller datasets but on larger ones you need to do the same principle but with the date using the bucket pattern.

Although this can be completely avoided by implementing a cache. Depends if you need realtime data or not. The following example is for stock trading data that must not be cached.

@copleykj
I tested this issue, it does not work with fast rendering.
@truedon Do you have a method tested with fast rendering?

Yes I have given it to you.

I don’t believe this to be the case. I don’t think you completely understand the question or the issue he is having.

The problem you are likely having is that the server has no idea about what data you need. fast-render needs to either be used with a fast-render aware router, or in conjunction with another package like communitypackages:react-router-ssr so that the server becomes aware of the data your application needs when it first loads.

How does that make any difference in building pagination bud?

When I build it’s same logic regardless of fast render and ssr. I have built with both and it has no difference at all I use the same pagination logic and reused my component literally just drop it in and set my props, regarding design pattern, I’ve used the same logic since asp and php days.

The url changes the page, I’ve not experienced any difference if it’s ssr or fast render that is just how it renders. What do you mean it doesn’t know? Don’t follow you at all with that.

When I code this, the links and component are the same.

The question here isn’t really about generating the UI for pagination. The question is how to make pagination work with fast-render and SSR. Without the server knowing about what page has been loaded, and what data that page requires for it to render, it cannot allocate that data to be sent to the client with the html payload.

I just use the url and the router bro not sure what you mean, have you checked the example app?

How about you point me to said example app. :man_shrugging:

https://github.com/CaptainN/meteor-react-starter

Just create a slug and page and apply the pagination logic to load, and for display do the same to create your slugs. Not sure if this is the latest and greatest way but that’s what I’ve been using.

There is also this package which uses same design pattern, per page etc https://github.com/Kurounin/Pagination/

Yes, if the app is properly rendered server side, this would make the server aware of the necessary data.

Is it possible for Fast Render to handle this issue?

Yes, if you are using FastRender.onPageLoad to server render your app. If you are using only Meteor’s onPageLoad from the server-render package then it will not.

@copleykj
I used exactly the following code:
Can be explained with an example.

   import React from "react";
    import { StaticRouter as Router } from "react-router-dom"
    import { FastRender } from 'meteor/communitypackages:fast-render'
    import { renderToString } from "react-dom/server"
    import { HelmetProvider } from 'react-helmet-async'
    import { LoadableCaptureProvider, preloadAllLoadables } from 'meteor/npdev:react-loadable'
    import Routes from "../imports/Routes/Routes";
    preloadAllLoadables().then(() => FastRender.onPageLoad(sink => {
        const context = {};
        const loadableHandle = {};
        const helmetContext = {};

        const html = renderToString(
            <LoadableCaptureProvider handle={loadableHandle}>
                <HelmetProvider context={helmetContext}>
                    <Router location={sink.request.url} context={context}>
                        <Routes />
                    </Router>
                </HelmetProvider>
            </LoadableCaptureProvider>
        );

        const { helmet } = helmetContext;
        sink.appendToHead(helmet.meta.toString());
        sink.appendToHead(helmet.link.toString());
        sink.appendToHead(helmet.title.toString());
        sink.renderIntoElementById('App', loadableHandle.toScriptTag() + html)
    }))

As far as I can see, this should work fine. Are you having an issue getting pagination to work, or is this a theoretical “will this work” question?