1

Trying to filter data using GraphQL variables and Next JS. How can I pass my state to the GraphQL variable "name" ?

handleSelectedFilter will update the filter state based on the selected option. I am expecting the value of the filter state to get passed to "name" variable.

Bare in mind we cannot use react hooks inside of Next js getStaticProps function, tried state management, custom hooks ..etc doesn't work with Next JS.

Any kind of help is much appreciated. Thanks in advance.

export async function getStaticProps() {

 const { data, errors } = await client.query({
    query: GET_LISTINGS,
    variables: {
        uri: '/listing/',
        name: filter?.city
    }
  })
  return {
    props: {
        data: data || [],
    },
    revalidate: 1
  }
}

const listings = ({ data }) => {
  const [filter, setFilter] = useState({
      city: '',
      area: '',
      type: '',
  })

  const handleSelectedFilter = e => {
    setFilter({ ...filter, [e.target.name]: e.target.value })
  }
}
export default listings

GrpahQL Schema below

export const GET_LISTINGS = gql`
query GET_LISTINGS( $name: String) {
listingCategoriesL: listingCategories(where: {name: [$name]}) {
   nodes {
     id
     name
     listings {
       edges {
          node {
           id
           title
          }
        }
      }
    }
  }
}

1 Answers1

2

With Next, your queries are processed at build time so you can't dynamically query in getStaticProps after the page is built. But you've got options.

If you want to query client-side, Apollo is probably the best choice frequently. I wrote up a whole approach on using Apollo to fetch dynamic data in a component.

For the select, I'd strongly recommend react-select. Great project, I use it all the time. You should probably have a static set of filter handles preset for your UI (because you wouldn't want a user to just open the filter and see nothing).

I'm not 100% sure what UI you're going for, but this would get you most of the way there...

import React from 'react'
import { useQuery, gql } from '@apollo/client'
import Select from 'react-select'

// Your query
const LISTINGS_DATA = gql`
  query GET_LISTINGS( $name: String) {
    listingCategoriesL: listingCategories(where: {name: [$name]}) {
      nodes {
        id
        name
        listings {
          edges {
            node {
              id
              title
            }
          }
        }
      }
   }
}
`

// How to style react-select
const selectStyles = {
  control: (provided, state) => ({
    ...provided,
    borderRadius: 0,
    fontWeight: 700,
    padding: '10px',
    textTransform: 'uppercase',
    minWidth: '250px'
  })
}

// Component
const Listings = ({ data }) => {

  const [filter, setFilter] = useState({
      city: '',
      area: '',
      type: '',
  })

  const handleSelectedFilter = e => {
    setFilter({ ...filter, [e.target.name]: e.target.value })
  }

  const selectOptions = [
    { value: x, label: 'Filter 1' },
  ]

  // Query for nav menu from Apollo, this is where you pass in your GraphQL variables
  const { loading, error, data } = useQuery(LISTINGS_DATA, {
    variables: {
      "name": filter,
    }
  })

  return (
   <>
     <Select 
        defaultValue={ selectOptions[0] }
        onChange={ event => handleSelectedFilter(event) }
        options={ selectOptions }
        styles={ selectStyles }
     />
   </>
  )
}
export default Listings
serraosays
  • 7,163
  • 3
  • 35
  • 60