pretty new to React so don't clown me to hard haha.
Essentially my goal is to fetch the data from my personal JSON server & render that data onto a "Slider" that I am creating.
I am following along with a tutorial and decided to give myself a challenge, the only difference is that where he just imported a data.js file with his data, I wanted to use JSON data / server instead.
The issues is that I'm not sure how to ".map()" through the data for each slide and render to the slider. I have a general idea of how but I'm not fully sure how to implement it correctly in the context of using JSON data with fetch requests.
I have fetched my JSON url and used .thens to string my responses & assign the data to a state setter function. When I console.log the data I receive the object successfully but twice.
Read online that I could use the first variable of state to .map(), attempted and has not worked.
Sorry if this has been touched on before, I have tried everything to find this info before asking but to no avail.
The error I receive is in regards to me using the state variable "slideIndx.map" not being a function.
What can I do here?
import {useState, useEffect} from 'react';
import { ArrowLeftOutlined, ArrowRightOutlined } from "@material-ui/icons";
import styled from "styled-components";
const Container = styled.div`
width: 100%;
height: 95vh;
display: flex;
// background-color: #b3f0ff;
position: relative;
overflow: hidden;
`;
const Arrow = styled.div`
width: 50px;
height: 50px;
background-color: #e6ffff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
bottom: 0;
left: ${props => props.direction === "left" && "10px"};
right: ${props => props.direction === "right" && "10px"};
margin: auto;
cursor: pointer;
opacity: 0.5;
z-index: 2;
`;
const Wrapper = styled.div`
height: 100%;
display: flex;
transform: translateX(0vw)
`
const Slide = styled.div`
width: 100vw;
height: 100vw;
display: flex;
align-items: center;
background-color: ${props => props.bg};
`
const ImgContainer = styled.div`
height: 100%;
flex:1;
`
const Image = styled.img`
padding-left: 30px;
align-items: left;
`
const InfoContainer = styled.div`
height: 80%;
flex:1;
padding: 30px;
`
const Title = styled.h1`
font-size: 50px
`
const Desc = styled.p`
margin: 50px 0px;
font-size: 20px;
font-weight: 500;
letter-spacing: 3px;
`
const Button = styled.button`
padding: 10px;
font-size: 20px;
background-color: transparent;
cursor: pointer;
`
const Slider = () => {
const [slideIndx, setSlideIndx] = useState(0);
const fetchSliderItems = () => {
fetch('http://localhost:3000/sliderItems')
.then(resp => resp.json())
.then(data => {
console.log(data)
setSlideIndx(data)
})
}
useEffect(() => {fetchSliderItems()}, [])
const handleClick = (direction) => {}
return (
<Container>
<Arrow direction="left" onClick={() => handleClick("left")}>
<ArrowLeftOutlined />
</Arrow>
// Here is where I am attempting to map over the items.
<Wrapper>
{fetchSliderItems.map((item) => (
<Slide bg={item.bg}>
<ImgContainer>
<Image src={item.img}/>
</ImgContainer>
<InfoContainer>
<Title>{item.title}</Title>
<Desc>{item.desc}</Desc>
<Button>SHOP NOW</Button>
</InfoContainer>
</Slide>
))}
</Wrapper>
<Arrow direction="right" onClick={() => handleClick("right")}>
<ArrowRightOutlined />
</Arrow>
</Container>
)
}
export default Slider
{
"sliderItems": [
{
"id": 1,
"img": "../images/model1.png",
"title": "SPRING CLEANING",
"desc": "DONT MISS OUR BEST COLLECTION YET! USE #FLATIRON10 TO RECEIVE 10% OFF YOUR FIRST ORDER",
"bg": "b3ecff"
},
{
"id": 2,
"img": "https://i.ibb.co/DG69bQ4/2.png",
"title": "SHOW OFF HOW YOU DRESS",
"desc": "WITH OUR HUGE SELECTION OF CLOTHES WE FIT ALL YOUR STYLING NEEDS",
"bg": "ccf2ff"
},
{
"id": 3,
"img": "../images/model1.png",
"title": "POPULAR DEALS",
"desc": "RECEIVE FREE SHIPPING ON ALL ORDERS OVER $50!",
"bg": "fe6f9ff"
}
]
}
CodePudding user response:
You should share the error you're getting. But based on the second screenshot, it looks like your array is wrapped in a sliderItems
object.
You want a raw array when you .map
. So maybe try setting your slideIndx
to the raw array by doing something like:
setSlideIndx(data.sliderItems)
Try confirming the shape of your state by console logging above your return
with:
console.log(slideIndx)
CodePudding user response:
You're calling map from fetchSliderItems.map
, but fetchSliderItems
is a function, not an array. You need to call map from the array containing the data, which in your case is slideIndx.sliderItems
.
What happens in your code is const [slideIndx, setSlideIndx] = useState(0);
initializes slideIndx
to 0
. When useEffect
runs fetchSliderItems
, you'll fetch the data and eventually the line setSlideIndx(data)
assigns data
to slideIndx
. Because your data is an object that holds and array in the sliderItems
property, the array can now be accessed in slideIndx.sliderItems
.
So fist thing you should do to fix it is change the useState
line to const [slideIndx, setSlideIndx] = useState([]);
, because you want your state variable to be an array. Then when you fetch the data you want to call setSlideIndx(data.sliderItems)
to assign your data to slideIndx
. Finally, in your jsx return you should use slideIndx.map
.