AdeleD / react-paginate

A ReactJS component that creates a pagination
MIT License
2.76k stars 628 forks source link

Render issues on Next.js 13.5.4 after upgrading from 13.4.12 #501

Open camcamcamcam opened 1 year ago

camcamcamcam commented 1 year ago

Bumped up my version of Next.js to silence a vulnerability notice, and after doing so react-paginate no longer works correctly. Getting around it for now by locking my version to 13.4.12, but not a fan of this solution.

Expected behaviour (on 13.4.12): Screenshot 2023-10-06 160247

<ul class="pagination col-span-full gap-3 flex justify-center font-bold my-16" role="navigation" aria-label="Pagination">
   <li class="previous disabled"><a class="h-full flex items-center rotate-180 mr-5 " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev"><img alt="Previous Page" loading="lazy" width="15" height="9" decoding="async" data-nimg="1" class="inline-block" style="color: transparent;" src="/_next/static/media/icon-arrow-right.0ababecc.svg"></a></li>
   <li class="selected"><a rel="canonical" role="button" class="flex font-black" tabindex="-1" aria-label="Page 1 is your current page" aria-current="page">1</a></li>
   <li><a rel="next" role="button" class="flex" tabindex="0" aria-label="Page 2">2</a></li>
   <li><a role="button" class="flex" tabindex="0" aria-label="Page 3">3</a></li>
   <li><a role="button" class="flex" tabindex="0" aria-label="Page 4">4</a></li>
   <li class="break"><a role="button" tabindex="0" aria-label="Jump forward">...</a></li>
   <li><a role="button" class="flex" tabindex="0" aria-label="Page 13">13</a></li>
   <li class="next"><a class="h-full flex items-center ml-5" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next"><img alt="Next Page" loading="lazy" width="15" height="9" decoding="async" data-nimg="1" class="inline-block" style="color: transparent;" src="/_next/static/media/icon-arrow-right.0ababecc.svg"></a></li>
</ul>

What happens (on 13.5.4): Screenshot 2023-10-06 160159

<ul class="pagination col-span-full gap-3 flex justify-center font-bold my-16" role="navigation" aria-label="Pagination">
   <li class="previous disabled"><a class="h-full flex items-center rotate-180 mr-5 " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev"><img alt="Previous Page" loading="lazy" width="15" height="9" decoding="async" data-nimg="1" class="inline-block" style="color: transparent;" src="/_next/static/media/icon-arrow-right.0ababecc.svg"></a></li>
   <ul role="navigation" aria-label="Pagination">
      <li class="previous disabled"><a class=" " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev">Previous</a></li>
      <li class="next"><a class="" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next">Next</a></li>
   </ul>
   <ul role="navigation" aria-label="Pagination">
      <li class="previous disabled"><a class=" " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev">Previous</a></li>
      <li class="next"><a class="" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next">Next</a></li>
   </ul>
   <ul role="navigation" aria-label="Pagination">
      <li class="previous disabled"><a class=" " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev">Previous</a></li>
      <li class="next"><a class="" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next">Next</a></li>
   </ul>
   <ul role="navigation" aria-label="Pagination">
      <li class="previous disabled"><a class=" " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev">Previous</a></li>
      <li class="next"><a class="" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next">Next</a></li>
   </ul>
   <li class="break"><a role="button" tabindex="0" aria-label="Jump forward">...</a></li>
   <ul role="navigation" aria-label="Pagination">
      <li class="previous disabled"><a class=" " tabindex="-1" role="button" aria-disabled="true" aria-label="Previous page" rel="prev">Previous</a></li>
      <li class="next"><a class="" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next">Next</a></li>
   </ul>
   <li class="next"><a class="h-full flex items-center ml-5" tabindex="0" role="button" aria-disabled="false" aria-label="Next page" rel="next"><img alt="Next Page" loading="lazy" width="15" height="9" decoding="async" data-nimg="1" class="inline-block" style="color: transparent;" src="/_next/static/media/icon-arrow-right.0ababecc.svg"></a></li>
</ul>

Here is the JS of one of the pages that has pagination, if that helps. All instances of ReactPaginate on this site are experiencing this.

import { useEffect, useState } from 'react';
import NextImage from 'next/image';
import ReactPaginate from 'react-paginate';

// assets
import iconArrowRight from '@/images/icon-arrow-right.svg';

// components
import EventList from '@/components/Event/EventsList';

export default function PaginatedEvents({ data }) {
  // pagination
  const [itemOffset, setItemOffset] = useState(0);

  // Simulate fetching items from another resources.
  // (This could be items from props; or items loaded in a local state
  // from an API endpoint with useEffect and useState)
  const events = data;

  const itemsPerPage = 6;
  const endOffset = itemOffset + itemsPerPage;
  const pageCount = Math.ceil(events.length / itemsPerPage);
  const currentEvents = events.slice(itemOffset, endOffset);

  // Invoke when user click to request another page.
  const [currentPage, setCurrentPage] = useState(0);
  const handlePageClick = (event) => {
    setCurrentPage(event.selected);
    const newOffset = (event.selected * itemsPerPage) % events.length;
    setItemOffset(newOffset);
  };

  const Pagination = () => (
    <ReactPaginate
      onPageChange={handlePageClick}
      pageRangeDisplayed={4}
      marginPagesDisplayed={1}
      pageCount={pageCount}
      forcePage={currentPage}
      pageLinkClassName='flex'
      activeLinkClassName='font-black'
      breakLabel='...'
      nextLinkClassName='h-full flex items-center ml-5'
      nextLabel={
        <NextImage
          src={iconArrowRight}
          className='inline-block'
          alt='Next Page'
        />
      }
      previousLinkClassName='h-full flex items-center rotate-180 mr-5'
      previousLabel={
        <NextImage
          src={iconArrowRight}
          className='inline-block'
          alt='Previous Page'
        />
      }
      renderOnZeroPageCount={null}
      className={'pagination col-span-full gap-3 flex justify-center font-bold my-16'}
    />
  );

  useEffect(() => {
    const eventList = document.getElementById('event-list');
    window.scrollTo({
      top: eventList.scrollTop,
      behavior: 'smooth',
    });

  }, [currentPage]);

  return (
    <div className='event-list' id='event-list'>
      <Pagination />
      <EventList events={currentEvents} />
      <Pagination />
    </div>
  );
}
martinharyanto commented 1 year ago

Yes, this also happens to me. Not sure why in development it is rendering correctly though. But on my staging env, it renders like this

image

this is my code

<ReactPaginate
    className="flex items-center justify-center"
    pageCount={metadata.pageCount}
    forcePage={metadata.page - 1}
    pageRangeDisplayed={1}
    marginPagesDisplayed={1}
    onPageChange={({ selected }) => onPageChange((selected += 1))}
    breakLabel="..."
    breakClassName="h-9 w-9 flex justify-center"
    containerClassName={"wif-pagination"}
    pageClassName="h-9 w-9 flex justify-center items-center ring-1 ring-inset ring-gray-300 -ml-[1px]"
    pageLinkClassName="leading-1"
    activeClassName="bg-wif-orange-2 text-white ring-0"
    previousClassName="relative inline-flex items-center rounded-l-md p-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0"
    nextClassName="relative inline-flex items-center rounded-r-md p-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0"
    previousLabel={
      <>
        <span className="sr-only">Previous</span>
        <svg
          className="h-5 w-5"
          viewBox="0 0 20 20"
           fill="currentColor"
           aria-hidden="true"
        >
          <path
            fillRule="evenodd"
            d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z"
            clipRule="evenodd"
          />
        </svg>
      </>
    }
    nextLabel={
      <>
        <span className="sr-only">Next</span>
        <svg
         className="h-5 w-5"
         viewBox="0 0 20 20"
         fill="currentColor"
         aria-hidden="true"
        >
          <path
            fillRule="evenodd"
            d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z"
            clipRule="evenodd"
          />
        </svg>
      </>
    }
  />
camcamcamcam commented 1 year ago

Ya it works fine when I am just running npm run dev, but is broken after a build. So it is something about the build process in 13.5 that is breaking it.

dawsnap commented 1 year ago

Same thing happening here!

extralsc commented 1 year ago

Same issue here.

nabtron commented 1 year ago

linked with nextjs update to 13.5.4 (13.5.3 works fine) https://github.com/vercel/next.js/issues/56406

jnovak-SM2Dev commented 1 year ago

Any update on this issue? Kind of a big problem.

camcamcamcam commented 1 year ago

I tracked it down to a specific commit that broke it.

https://github.com/vercel/next.js/commit/83c18deafe4f133f74ef2b1e0512228098d48cba

It has something to do with the SWC minifier. If you set keep_fnames to false in packages/next/src/build/webpack/plugins/terser-webpack-plugin/src/index.ts then this problem goes away.

keep_fnames (default false) -- Pass true to not mangle function names. Pass a regular expression to only keep function names matching that regex. Useful for code relying on Function.prototype.name.

Workaround You can add swcMinify: false to your next.config.js file. It will go back to using the Terser minifier, which was the default before v13.

jnovak-SM2Dev commented 1 year ago

@camcamcamcam I've had swcMinify: true in my project since day one without issues. It's odd you have to set it to false now, but I guess that's a workaround for now.

camcamcamcam commented 1 year ago

I think it is because they changed the defaults for the SWC minifier in 13.5.4, from the default of keep_fnames: false to keep_fnames: true.

I'm honestly not sure why this affects react-paginate, but it does. It at least does explains why it only happens in builds.

lutfi-haslab commented 1 year ago

Thanks for creating this issue. I also facing same issue: Why this happen? Issue happen after upgrade next to version 13.5.4 Here in Dev server: image Here in Prod server: image

lutfi-haslab commented 1 year ago

@camcamcamcam I've had swcMinify: true in my project since day one without issues. It's odd you have to set it to false now, but I guess that's a workaround for now.

Does it affect for performance? since it is SWC thing

camcamcamcam commented 1 year ago

@lutfi-haslab Not in anyway that I have noticed in production, since it is still being minified, just using the pre v13 minifier. The only difference I have noticed, or at least can measure, is that the build take ever so slightly longer.

camcamcamcam commented 1 year ago

504

sadaffathali commented 1 year ago

I have this issue in production too. Kind of a big problem for my company.

Next: 13.5.4

erfan-amani commented 1 year ago

I faced same issue when I updated Next version to 13.5.4. As a temporary solution, I downgraded Next.js to the previous version. However, this is not an ideal solution. I would appreciate it if the issue could be fixed to work correctly with the new version.

sabamohamadi commented 1 year ago

I have same issue :)

ronmicha commented 1 year ago

Having the same issue. Had to use this workaround

lutfi-haslab commented 1 year ago

I was able to show it again after downgrade to next 13.5.2 and react-paginate 8.1.4 as mention below https://github.com/vercel/next.js/issues/56406#issuecomment-1752461866

ORizzo commented 1 year ago

I was having the same issue, and just upgrade the next.js version to 15.5.5 (latest version) solved my issue.

JavierMartinz commented 1 year ago

It's still broken for v15.5.5 and swcMinify: true.

maiconcarraro commented 1 year ago

@ORizzo

I was having the same issue, and just upgrade the next.js version to 15.5.5 (latest version) solved my issue.

which react-paginate version? still broken here like @JavierMartinz ^

camcamcamcam commented 1 year ago

@ORizzo

I was having the same issue, and just upgrade the next.js version to 15.5.5 (latest version) solved my issue.

which react-paginate version? still broken here like @JavierMartinz ^

I just updated to next@15.5.5, and trying with both react-paginate@8.2.0 and react-paginate@8.1.5, and can confirm it is still broken.

ORizzo commented 1 year ago

Sorry I forgot to send my specs.

Versions: nextjs - 13.5.5 react-paginate: 8.2

Config: nextjs.config.js - swcMinify: false.

E1NSER commented 1 year ago

Same issue in 13.5.6

swcMinify: false Does the trick but I should not be the solution for the future. Hopefully, there will be a better fix

tdn352001 commented 1 year ago

same issue

Kepron commented 1 year ago

Same issue

next@13.5.6 react-paginate@8.2.0

jw-blazity commented 1 year ago

Still exists on next@14.0.0

E1NSER commented 1 year ago

Same issue in 13.5.6

swcMinify: false Does the trick but I should not be the solution for the future. Hopefully, there will be a better fix

Disabling SWC Minifer will not be an option in the next major version. Please report any issues you may be experiencing to https://github.com/vercel/next.js/issues

For now it works by disabling the "swcMinify" but it will be removed by Next in the future.

timomedia commented 1 year ago

Same error

timomedia commented 1 year ago

Same issue in 13.5.6 swcMinify: false Does the trick but I should not be the solution for the future. Hopefully, there will be a better fix

Disabling SWC Minifer will not be an option in the next major version. Please report any issues you may be experiencing to https://github.com/vercel/next.js/issues

For now it works by disabling the "swcMinify" but it will be removed by Next in the future.

This actually works, but I don't know if it affects performance the way nextjs described.

balcieren commented 1 year ago

same issue

wlgns2223 commented 1 year ago

Same Issue. I hope it is resolved as soon as possible

saifbechan commented 1 year ago

This is working again for me for nextjs >= 14.0.2 😀

maiconcarraro commented 1 year ago

This is working again for me for nextjs >= 14.0.2 😀

same 🙌

nadeem-golflan commented 1 year ago

facing the same issue.

Vitaurus commented 1 year ago

I got the same problem after installing "framer-motion", but after updating next >= 14.0.2 all worked correctly

jvdhr commented 10 months ago

Updating to 14.0.4 solved the problem for me.

glenmoreilagan commented 3 months ago

adding swcMinify: false in next.config.js works for me.