I am calling a standard JSON file using fetch on a React Hooks project. (I'm mocking a server using JSON-Server to read the local json file)
In my main function, I'm calling a variable and a function, like any normal React Hook, and setting it to an empty array because I'm calling API data using fetch.
let [items, setItems] = useState([]);
Then I'm making my actual fetch call to my mock server
const fetchItems = async () => {
const url = "http://localhost:3002/learn";
const response = await fetch(url);
items = await response.json();
setItems(items);
console.log(items[0].title);
}
The console.log(items[0].title)
does in fact return the correct value.
If I wanted to display all results, the following would even work.
{items.map((item) =>
<img src={item.source} alt={item.title} title={item.title} className="img-fluid mx-auto d-block" />
)}
However, once I want to display a single value in my return, I get an error message saying: "TypeError: Cannot read property 'source' of undefined" The code that I'm using, just to test at first is the same exact thing as my console.log
from before.
<img src={items[0].source} alt={items[0].title} title={items[0].title} className="img-fluid mx-auto d-block" />
Am I missing a major step that allows me to use the fetched info in my return?
If I were to hard-code my JSON data on the same component, it would work. I feel like it has something to do with fetch. I was looking at this question, and it's similar, but not the same thing. I'm also using hooks and also not axios. Can't display data after fetch
UPDATE: The JSON file looks something like this:
{
"learn": [
{
"id": 1,
"title": "Angular JS",
"source": "./images/logo-angular-js.png"
},
{
"id": 2,
"title": "Firebase",
"source": "./images/logo-firebase.png"
},
{
"id": 3,
"title": "GraphQL",
"source": "./images/logo-graphql.png"
}
]
}
On your first render, items
has a length of 0, so items[0]
is going to be undefined
. You're likely trying to render before that first item has loaded.
Check if items[0]
is defined before trying to access items[0].source
and the like.
function YourComponent() {
const [items, setItems] = useState([]);
useEffect(() => {
fetchItems();
}, []);
const fetchItems = async () => {
const url = "http://localhost:3002/learn";
const response = await fetch(url);
items = await response.json();
setItems(items);
console.log(items[0].title);
}
if (!items.length) {
return null;
}
return (
<img
src={items[0].source}
alt={items[0].title}
title={items[0].title}
className="img-fluid mx-auto d-block" />
);
}
On the first render, this will cause nothing to be output. After the setItems
call is made, the component will re-render, and this time (if there were items being set), it'll render your item.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.