Next.js Discord

Discord Forum

Toggling between asc/desc sorting problem

Unanswered
Red-billed Tropicbird posted this in #help-forum
Open in Discord
Red-billed TropicbirdOP
Hi, I want to somehow be able to sort the name/email inside my component, and I want it to be in both directions (e.g. asc/desc).
Right now its only in ascending order, and that works fine for a server component.

However, if I have to implement descending order then I will run into two problems if I am not mistaken. I need to somehow have a useState that will toggle the query parameter depending on when I click the name/email. That would make it into a client component.

But then I cannot use async/await to fetch the API, as that needs to be in a server component. I am a bit lost.

14 Replies

Red-billed TropicbirdOP
This is my \app\users\page.tsx code where I get the searchParams:
import UserTable from './UserTable'

interface Props {
  searchParams: {
    sortOrder: string
  }
}

async function UsersPage({ searchParams: { sortOrder } }: Props) {
  return (
    <>
      <h1>Users</h1>
      <UserTable sortOrder={sortOrder} />
    </>
  )
}

export default UsersPage

This is my app\users\UserTable.tsx file where I handle the fetch request, sorting and displaying in a table:
import Link from 'next/link'
import { sort } from 'fast-sort'

interface Geo {
  lat: string
  lng: string
}

interface Address {
  street: string
  suite: string
  city: string
  zipcode: string
  geo: Geo
}

interface Company {
  name: string
  catchPhrase: string
  bs: string
}

interface User {
  id: number
  name: string
  username: string
  email: string
  address: Address
  phone: string
  website: string
  company: Company
}

interface Props {
  sortOrder: string
}

async function UserTable({ sortOrder }: Props) {
  const res: Response = await fetch(
    'https://jsonplaceholder.typicode.com/users'
  )
  const users: User[] = await res.json()

  const ascSortUsers = sort(users).asc(
    sortOrder === 'email' ? (user) => user.email : (user) => user.name
  )

  return (
    <table className='table table-bordered'>
      <thead>
        <tr>
          <th>
            <Link href={'/users?sortOrder=name'}>Name</Link>
          </th>
          <th>
            <Link href={'/users?sortOrder=email'}>Email</Link>
          </th>
        </tr>
      </thead>
      <tbody>
        {ascSortUsers.map((user) => (
          <tr key={user.id}>
            <td>{user.name}</td>
            <td>{user.email}</td>
          </tr>
        ))}
      </tbody>
    </table>
  )
}

export default UserTable
Asian black bear
Is the sorting server side or u do it in the client?
@Asian black bear Is the sorting server side or u do it in the client?
Red-billed TropicbirdOP
The sorting is done in the UserTable file which is server side. that was my best idea
Im not sure whether if its the best advice but i would say its fine for the table to be client side.
Its going to change on user interaction alot, like filtering, sorting etc
@Red-billed Tropicbird The sorting is done in the `UserTable` file which is server side. that was my best idea
Asian black bear
Why not fetch in the page then pass it the table as a prop ? This way Ithink u will achieve what u want
Usually fetching should be in the page then u pass the result to the components that need it
@Asian black bear Why not fetch in the page then pass it the table as a prop ? This way Ithink u will achieve what u want
Red-billed TropicbirdOP
Oh smart. That way I can make the user table a client component
@Red-billed Tropicbird Oh smart. That way I can make the user table a client component
Asian black bear
not smart brother its just how we usually fetch in next (in the page)
btw even with the way ur working u can still achieve what u want by making the button that does what u want client then import it in that table
@Asian black bear btw even with the way ur working u can still achieve what u want by making the button that does what u want client then import it in that table
Red-billed TropicbirdOP
Ah in that case I'd make the button client and then use state in it. But I can hear from you that you prefer to fetch in the page file itself
@Red-billed Tropicbird Ah in that case I'd make the button client and then use state in it. But I can hear from you that you prefer to fetch in the page file itself
Asian black bear
its not my opinion , this is what next suggest devs to do , fetch in the page then pass via props to ur components