Handling checkbox filters in a NextJS app with Groq queries and React state
25 replies
Last updated: Aug 10, 2022
I'm trying to create a checkbox filter in my NextJS app. How would I handle filtering out sanity documents that don't meet the checkbox requirements? (I would post code but I don't even know where to begin)
Aug 2, 2022, 11:27 AM
K
Once you have a boolean field in your schema, you can just use
foo == trueor
foo == falsein your Groq query. 🙂
Aug 2, 2022, 12:01 PM
hmm okay so for example if I have a query like
How would I dynamically change this with the checkbox? or would each checkbox call a new query?
*[_type == "fruit"]{ name, image }
Aug 2, 2022, 12:26 PM
K
I’m a little confused. What are you trying to do? 😅
Aug 2, 2022, 2:52 PM
K
My understanding was that your schema (
fruithere) has a boolean field that you want to query. But I might have misunderstood you.
Aug 2, 2022, 2:53 PM
in next im using
getServerSidePropsto fetch data from sanity using a groq query of the above, but I want to be able to filter it after the initial fetch to only show specific documents that have been checked off
Aug 2, 2022, 3:12 PM
And it may be that I should be using a different method for fetching but there's other data I need from sanity on the page as well which is part of the getServerSideProps query
Aug 2, 2022, 3:13 PM
Hi Brian! If I’m understanding correctly, you can include the boolean in your projection and then handle the boolean when you map over your fruits. For example, if your
Then once
fruitdocument has a boolean called
hide, your query might look like:
*[_type == "fruit"]{ name, image, hide }
getServerSidePropsreturns your array of `fruit`s, you might do:
return fruits.map(fruit => fruit.hide !== true ? fruit : null)
fruitsmay need to be destructured, depending on your setup. You’ll also likely want to modify
fruit.hide !== trueto your liking—it’s worth noting that unless you’ve handled indeterminate booleans explicitly in your Studio (with validation or initial values),
trueand
falsearen’t the only options (i.e.,
fruit.hide !== truewould return both
falseand indeterminate values).
Aug 2, 2022, 7:19 PM
Thanks! I'm not sure I really understand how the checkbox filter on the front end will be able to do this, but I guess thats more of a matter of checkbox validation and handling state within next
Aug 2, 2022, 7:31 PM
Maybe I misunderstood. Is the boolean part of your schema, or is it more along the lines that you’ll have a bunch of checkboxes on your front end for different fruits and you want to only return the documents that have that fruit checked?
Aug 2, 2022, 7:34 PM
The later, I could add the boolean to my schema if needed but essentially I'm trying to have checkboxes on the front end that will be able to filter the list of fruit documents based on whether they are checked or not
Aug 2, 2022, 7:36 PM
And apologies for posting this in groq if it's not really a groq question. I wasn't sure if I should be writing a new query or what
Aug 2, 2022, 7:40 PM
Not to worry!
In that case, the boolean won’t go in your schema as I originally suggested as it doesn’t seem to be content but rather a means of filtering. If you’re looking for something like
this CodeSandbox demo , then hopefully that can help (it’s using class components but the fundamentals are similar even if you’re using hooks).
In that case, the boolean won’t go in your schema as I originally suggested as it doesn’t seem to be content but rather a means of filtering. If you’re looking for something like
this CodeSandbox demo , then hopefully that can help (it’s using class components but the fundamentals are similar even if you’re using hooks).
Aug 2, 2022, 7:53 PM
One other quick question how would state in React translate to Next?ex.
state = { products: productsList, categories: { first: false, second: false, third: false, forth: false, } };
Aug 2, 2022, 8:25 PM
That example I provided uses class components, so it probably wasn’t the best example to send you (though it still works in React as well as Next.js). I’ve updated it to use hooks (i.e.,
One change I made was to show nothing if no boxes are checked (the previous example showed everything). You can revert that by changing
useState) here: https://codesandbox.io/s/react-checkboxes-filter-forked-4oz39s?file=/src/App.js
One change I made was to show nothing if no boxes are checked (the previous example showed everything). You can revert that by changing
nullto
productson line 49 of App.js.
Aug 2, 2022, 10:09 PM
When using this with sanity data, can I use the
_idthat sanity gives documents by default for the id that needs to be set to map things in
<li id={id}>?
Aug 10, 2022, 8:49 PM
Yes, as long as the
_idwill always be unique in your map, it’s the perfect candidate to use as the key in React.
Aug 10, 2022, 8:51 PM
So to do that I would just change the id to be
_idlike this?
const ProductList = (props) => { const { products } = props; const renderProducts = products?.map(({ _id, title, category }) => { return ( <li key={_id}> <Product title={title} category={category} /> </li> ); }); return <ul>{renderProducts}</ul>; }; export default ProductList;
Aug 10, 2022, 9:02 PM
hmm on the front end I'm getting a hydration err and in the console I'm getting
Error: Text content does not match server-rendered HTML.
Warning: Each child in a list should have a unique "key" prop. Check the top-level render call using <ul>. See <https://reactjs.org/link/warning-keys> for more information. at li at ProductList (webpack-internal:///./components/ProductList.js:14:13)
Aug 10, 2022, 9:05 PM
Sanity– build remarkable experiences at scale
Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.