There's a couple of problems with this snippet:
{videos.id.map((video) => {
<div key={video.id} {...videos}></div>
})}
In your code the
videosvariable is initiallynull, and then (after fetching) — an array. Arrays don't haveidproperty, and accessing properties ofnullis an illegal operation. You might want to first ensure that this is an array, rather thannull, and then also remove the ".id" part.You don't return anything from
.map()! Yes, you create a JSX element for each item of the array, but they are destroyed unused after that.
Consider using this instead:
{videos && videos.map((video) => (
<div key={video.id} {...videos}></div>
))}
Another problem is with variables' visibility:
import videos from "./path/to/data.json";
// and then later
const [ videos, setVideos ] = useState(null);
That first variable videos (the imported one) is not visible anymore, it got shadowed by the second one.
You either rename the second variable to prevent shadowing, or remove the first one completely as it is unused.
Next thing that I can see is that the code can't make up its mind about what it is actually trying to accomplish. On one hand, router provides an ID to a specific, particular video, which means that we're trying to show only one video. On the other hand though, the FeaturedVideo component is almost a perfect fit for showing the list of all the videos.
Judging from the names and overall setup though, it is somewhat clear that you're trying to show one video, not the whole list.
Looks like you're using react-router. If that's true, in FeaturedVideo you need to access the video ID, provided by router. Given that it is v5+, you can use useParams hook for that:
import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router';
const [ video, setVideo ] = useState(null); // 'video', not 'videos'
const { videoID } = useParams();
useEffect(() => {
fetch("/src/data/data.json")
.then((res) => res.json())
.then((videos) => videos.filter((video) => {
return video.id === videoID;
}))
.then((matched) => setVideo(matched[0]));
}, []);
// Here `video` variable holds either `null` or the first matched array item.
// Render it using suggestions above.
References:
.map()method of arrays&&operator (see Description section)- Variable shadowing
- React Router Hooks
There's a couple of problems with this snippet:
{videos.id.map((video) => {
<div key={video.id} {...videos}></div>
})}
In your code the
videosvariable is initiallynull, and then (after fetching) — an array. Arrays don't haveidproperty, and accessing properties ofnullis an illegal operation. You might want to first ensure that this is an array, rather thannull, and then also remove the ".id" part.You don't return anything from
.map()! Yes, you create a JSX element for each item of the array, but they are destroyed unused after that.
Consider using this instead:
{videos && videos.map((video) => (
<div key={video.id} {...videos}></div>
))}
Another problem is with variables' visibility:
import videos from "./path/to/data.json";
// and then later
const [ videos, setVideos ] = useState(null);
That first variable videos (the imported one) is not visible anymore, it got shadowed by the second one.
You either rename the second variable to prevent shadowing, or remove the first one completely as it is unused.
Next thing that I can see is that the code can't make up its mind about what it is actually trying to accomplish. On one hand, router provides an ID to a specific, particular video, which means that we're trying to show only one video. On the other hand though, the FeaturedVideo component is almost a perfect fit for showing the list of all the videos.
Judging from the names and overall setup though, it is somewhat clear that you're trying to show one video, not the whole list.
Looks like you're using react-router. If that's true, in FeaturedVideo you need to access the video ID, provided by router. Given that it is v5+, you can use useParams hook for that:
import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router';
const [ video, setVideo ] = useState(null); // 'video', not 'videos'
const { videoID } = useParams();
useEffect(() => {
fetch("/src/data/data.json")
.then((res) => res.json())
.then((videos) => videos.filter((video) => {
return video.id === videoID;
}))
.then((matched) => setVideo(matched[0]));
}, []);
// Here `video` variable holds either `null` or the first matched array item.
// Render it using suggestions above.
References:
.map()method of arrays&&operator (see Description section)- Variable shadowing
- React Router Hooks
You are correct in using that useEffect hook. You want this data to load on component mount.
Assuming that URL returns JSON you can simply:
fetch(url)
.then(res => res.json().then(videos => setVideos(videos)));
reactjs - useEffect and useState to fetch API data - Stack Overflow
reactjs - how to use react fetch() with useEffect hook and map the fetched data - Stack Overflow
Setting React state from JSON data in useEffect
Fetching json api using react ( useeffect ) - javascript
Videos
You have to change {} to array first to be able to map over it. You can easily place ? after test like this. or make in the default value of the state a default value for item name. because this error results as you map over an empty object.
import { useEffect, useState } from 'react';
function App() {
const[test, setTest] = useState([{name:"default"}])
useEffect(() => {
testfunc()
}, [])
async function testfunc(){
let api = await fetch('https://jsonplaceholder.typicode.com/users')
let apijson = await api.json()
setTest(apijson)
}
return (
<div className="App">
{
test?.map((item) => {
return(
<div>
{item.name}
</div>
)
})
}
</div>
);
}
export default App;
You can't map on an object {}, so you should need to define an array [] for the base state :
const[test, setTest] = useState([])
