<div id="app"></div>
*,*::before,*::after {
box-sizing:border-box;
margin:0;
}
.carousel-container{
height:100vh;
width:100vw;
display:flex;
position:relative;
}
.carousel-img {
position:absolute;
inset:0;
height:100%;
width:100%;
object-fit:cover;
object-position:center;
opacity:0;
transition:200ms opacity ease-in;
transition-delay:200ms;
}
.carousel-img.active {
opacity:1;
transition-delay:0ms;
}
.carousel-btn{
position:absolute;
cursor:pointer;
top:50%;
font-size:4rem;
z-index:2;
background:none;
border:none;
transform:translateY(-50%);
color:rgba(255,255,255,0.5);
background-color:rgba(0,0,0,0.1);
border-radius:0.25rem;
padding:0.5rem;
}
.carousel-btn:hover,
.carousel-btn:focus {
color:white;
background-color:rgba(0,0,0,0.2);
}
.carousel-btn:focus {
outline:2px solid black;
}
.carousel-btn.prev{
left:1rem;
}
.carousel-btn.next{
right:1rem;
}
const {useEffect,useState,useRef} = React
const URL = `https://www.reddit.com/r/aww/top/.json?t=all`
const App = () => {
const [images, setImages] = useState([])
const [errorImg, setErrorImg] = useState("")
const [slide,setSlide] = useState(0)
const handleNext = ()=> {
setSlide(prev => prev === images.length-1 ? 0: prev+1)
}
const handlePrev = ()=> {
setSlide(prev => prev === 0 ? images.length-1: prev-1)
}
if(errorImg.length > 0){
<p>{`Error Fetching images ${errorImg}`}</p>
}
useEffect(()=>{
console.log("ONCE FETCH")
fetch(URL).then(res => res.json()).then(final => {
const data = final.data.children.map(o => o.data.url_overridden_by_dest).filter(url => url.slice(-4) === ".jpg")
setImages(data)
}).catch(err => setErrorImg(err))
},[])
const ref = useRef()
useEffect(()=>{
console.log("Always")
ref.current = handleNext
})
useEffect(()=>{
console.log("SET INTERVAL ONE")
if(ref.current != null){
const id = setInterval(()=>{
ref.current()
},3000)
}
return ()=> clearInterval(id)
},[])
const imageData = images.length === 0 ? <p>Loading...</p> : images.map((img,idx) => <img src={img} alt="response img" key={img} className={`carousel-img ${idx === slide ? "active":""}`}/>)
return <div className="carousel-container">
<button onClick={handleNext} className="carousel-btn next">⇛</button>
<button onClick={handlePrev} className="carousel-btn prev">⇚</button>
{imageData}
</div>
}
ReactDOM.render(<App />, document.getElementById('app'));
View Compiled
This Pen doesn't use any external CSS resources.