Sanity fetch returns undefined: "item is not defined" error in React

15 replies
Last updated: Jul 31, 2022
Hello! I'm building my first React app with Sanity following User's tutorial here . I've made a document type called 'item' in my Sanity Studio, but whenever I try to pull fields from it i.e. {item.title}, I get errors saying "'item' is not defined" at each line. I've set up my schemas as per the video, and I'm using this fetch:

useEffect(() => {
`sanityClient.fetch(
*[_type == "item"]{

title,

slug,

mainImage,

}
)`
.then((_data_) => setItemData(_data_))

.catch(console.error);

})
AI Update

I can see the issue in your code! You have a syntax error in your useEffect hook. The backticks () are in the wrong place - they should be wrapping the GROQ query string, not the entire sanityClient.fetch()` call.

Here's the corrected version:

useEffect(() => {
  sanityClient.fetch(
    `*[_type == "item"]{
      title,
      slug,
      mainImage,
    }`
  )
  .then((data) => setItemData(data))
  .catch(console.error);
}, []); // Don't forget the dependency array!

Key fixes:

  1. Backticks placement: Move the backticks to wrap only the GROQ query string (the part inside fetch()), not the entire function call
  2. Dependency array: Add an empty array [] as the second argument to useEffect - without this, your fetch will run on every render, causing an infinite loop!

Additional tips:

  • Make sure you've initialized sanityClient properly at the top of your file (usually imported from a client.js file)
  • Ensure itemData is initialized as an empty array: const [itemData, setItemData] = useState([])
  • When mapping over the data, you'd do something like:
    {itemData && itemData.map((item) => (
      <div key={item._id}>
        <h2>{item.title}</h2>
      </div>
    ))}

The "item is not defined" error you're seeing is likely because the fetch isn't working due to the syntax error, so itemData remains empty or undefined. Once you fix the backticks and add the dependency array, your data should load properly and you'll be able to access item.title when mapping over the results.

Show original thread
15 replies
The error doesn’t come from here. This code snippet is fine.
Hi User, thanks for replying. Do you have any idea where it could be coming from – somewhere further back in the chain maybe? I can send more code privately if you're up for helping.
Can you show the actual error please? Because
item is not defined
means it‘s something about an
item
constant, which doesn’t show in the code you shared.
That's the error, and here's the full Home.js:
import { useState, useEffect } from 'react';
import { NavLink, Link } from 'react-router-dom';
import './Home.css';
import sanityClient from '../client';

export default function Home() {
  const [itemData, setItemData] = useState(null);

  useEffect(() => {
    sanityClient
      .fetch(
        `*[_type == 'item']{
            title,
            slug,
            mainImage,
            game,
            category,
            publishedAt,
            caption
        }`
      )
      .then((data) => setItemData(data))
      .catch(console.error);
  });

  return (
    <div>
      <section className='intro flex align-items-flex-end justify-space-between'>
        <h1>
          Heading here
        </h1>
        <NavLink to='/items' className='btn btn--inverse'>
          View all
        </NavLink>
      </section>
      <section className='latest-items'>
        <div className='grid w-100'>
          <div className='card flex'>
            <Link to={'/items/' + item.slug.current} key={item.slug.current}>
              <div className='card__img'></div>
              <div className='card__title'>
                <h4>{item.title}</h4>
              </div>
            </Link>
            <div className='card__filters flex'>
              <a href='' className='game'>
                {item.game}
              </a>
              <a href='' className='category'>
                {item.category}
              </a>
            </div>
          </div>
        </div>
      </section>
    </div>
  );
}
Yeah, I mean the error is pretty explicit. You refer to a variable called
item
all throughout your JSX, but it doesn’t exist?
In the tutorial, User sets it up that way only hers is {project.title}, {project.slug} etc. with no errors. I changed 'project' to 'item' throughout (including the schemas etc.) but I'm getting that error....
I've been back through everything a few times but admittedly I'm brand new to Sanity.
This is not a Sanity issue here, it’s is really a JavaScript error: the
item
constant you reference all over doesn’t exist, hence the error.
If you’re using Next.js, you will want to perform your query in
getStaticProps
, and pass down the data from Sanity to your component. Fetching data in a
useEffect
hook is not recommended and goes against Next.js principles.
No, just vanilla React.
Like create-react-app or did you build your own thing?
create-react-app, I followed the tutorial I linked.
Alright. Then you have two issues right now:• You reference a variable called
item
but you store your data in a
itemData
state.• You fetch an array of items, but try to render a single one.
I forgot to map over everything! That's fixed the
item
error, but now I get a blank white screen shortly after the page loads – presumably right as that array is loaded. Appreciate your help!
Check your console for errors. 🙂

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?