title: how to paginate through user notifications without mixing them up?
body: <p>i'm working on a MERN app where the user can receive notifications on certain events, the user can then open the notification page where he can view his notifications, the issue that i have is the notifications have a &quot;seen&quot; state, the notifications that aren't seen will always be on top of the notification results..but say the user clicks on a notification which sets it as seen and then paginates further down the notification list by clicking on &quot;show more&quot; btn, he will find that earlier notification waiting for him in the bottom, basically it's duplicating..how can i fix this?</p>
  <p>express controller for notifications</p>
  <pre><code>router.get(&quot;/&quot;, verifyUser, (req, res) =&gt; {
      let userId = res.locals.user._id; //from the verify user MW, unrelated to question
      let pageNum = req.query.page;
  
      const options = {
          page: pageNum,
          limit: 8,
          sort: { seen: 1, createdAt: -1 }
      };
      Notification.paginate({ receiver: userId }, options, (err, result) =&gt; {
          if (err) {
              console.log(err);
              res.sendStatus(400);
          } else {
              res.status(200).json(result);
          }
      })
  })
  </code></pre>
  <p>react</p>
  <pre><code>  function Notifications(){
      let { texts } = useContext(LangContext);
      let [notificationsList, setNotificationsList] = useState([]);
      let [isPending, setIsPending] = useState(true);
      let [notiPage, setNotiPage] = useState(1);
      let [hasNext, setHasNext] = useState(false);
  
      function getNotifications() {
          axios.get(`/api/notification?page=${notiPage}`).then(result =&gt; {
              console.log(result);
              setNotificationsList([...notificationsList, ...result.data.docs]);
              if (result.data.hasNextPage) {
                  setNotiPage(result.data.nextPage);
                  setHasNext(true);
              } else {
                  setHasNext(false);
              }
              setIsPending(false);
          }).catch(err =&gt; {
              console.log(err);
              setIsPending(false);
          })
      }
  
  
      //update notification seen status on the backend as well as on the front end
      function toggleNotificationView(id, seen) {
          let viewStatus = !seen;
          axios.put(`/api/notification/${id}`, { seen: viewStatus }).then(result =&gt; {
              console.log(result);
              let notiArray = [...notificationsList];
              let index = notiArray.findIndex(noti =&gt; {
                  return noti._id == id;
              })
              let editedNoti = notiArray[index];
              editedNoti.seen = viewStatus;
              notiArray.splice(index, 1, editedNoti);
              setNotificationsList(notiArray);
          }).catch(err =&gt; {
              console.log(err);
          })
      }
  
    return  &lt;div&gt;
              &lt;div className=&quot;d-flex flex-column justify-content-center align-content-center my-3&quot;&gt;
                  {notificationsList.map(notification =&gt; {
                      return (&lt;div key={notification._id} id={notification._id} className=&quot;w-70 mx-auto&quot;&gt;
                          &lt;div className={`d-flex justify-content-between ${!notification.seen ? &quot;new-notification&quot; : &quot;&quot;}`}&gt;
                              &lt;a className=&quot;text-decoration-none text-dark&quot; href={notification.srcInfo.link}&gt;
                                  &lt;div className={`d-flex justify-content-start align-items-center`}&gt;
                                      &lt;img src={notificationBell} width={100} height={100} /&gt;
                                      &lt;p className=&quot;text-start fs-4 mx-4&quot; &gt;{parseNotification(notification)}&lt;/p&gt;
                                  &lt;/div&gt;
                              &lt;/a&gt;
                              &lt;div className=&quot;noti-dropdown noselect align-self-start&quot;&gt;
                                  &lt;i onClick={toggleDropDown} className=&quot;bi bi-three-dots-vertical fs-4&quot;&gt;&lt;/i&gt;
                                  &lt;ul className=&quot;noti-dropdown-options px-0 fs-5&quot;&gt;
                                      &lt;li onClick={() =&gt; { deleteNotification(notification._id) }}&gt;{texts.deleteNotification}&lt;/li&gt;
                                      &lt;li onClick={() =&gt; { toggleNotificationView(notification._id, notification.seen) }}&gt;  {notification.seen ? texts.markNotificationNotSeen : texts.markNotificationSeen}&lt;/li&gt;
                                  &lt;/ul&gt;
                              &lt;/div&gt;
                          &lt;/div&gt;
                          &lt;hr className=&quot;text-main&quot; /&gt;
                      &lt;/div&gt;)
                  })}
              &lt;/div&gt;
              {hasNext &amp;&amp; &lt;h4 onClick={getNotifications} className=&quot;mx-auto text-center text-main text-decoration-underline&quot;&gt;&lt;span className=&quot;cursor-pointer&quot;&gt;{texts.notificationShowMore}&lt;/span&gt;&lt;/h4&gt;}
          &lt;/div&gt;
          }
  
  </code></pre>
  <p><a href="https://i.stack.imgur.com/Lwbdc.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Lwbdc.png" alt="enter image description here" /></a></p>
  <p><a href="https://i.stack.imgur.com/dC0iE.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/dC0iE.png" alt="enter image description here" /></a></p>
  <p>the problem is happening because i'm sorting by seen while paginating, what can i do about this?</p>