I have a quiz game where you have to remember the items(from images) and answer the quiz. First,4 images are shown with the time interval of 2 secs and after that the 4 quiz will start. I have Images component(which display images in intervals) and Quiz component. I want to hide the images component once it is finished and show the quiz. I tried to do it using conditional rendering but its not working.
import { useState, useEffect } from "react";
import Quiz from "./Quiz.js";
import Images from "./Images";
import "./styles.css";
const images = [
"https://picsum.photos/id/1/200/300",
"https://picsum.photos/id/2/200/300",
"https://picsum.photos/id/3/200/300",
"https://picsum.photos/id/4/200/300"
];
export default function App() {
const [image, setImage] = useState();
const [showImages, setShowImages] = useState(true);
const [showQuestions, setShowQuestions] = useState(false);
useEffect(() => {
const function1 = () =>
images.forEach((c, i) => setTimeout(() => setImage(c), i * 2000));
function1();
//setShowImages(false);
}, []);
return (
<div className="App">
<div className="screen">
{showImages && <Images image={image} />}
{showQuestions && <Quiz />}
</div>
</div>
);
}
codesanbox link: https://codesandbox.io/s/elastic-snowflake-qo1nz7?file=/src/App.js
CodePudding user response:
I hope this will solve your problem.
useEffect(() => {
setShowQuestions(false);
setShowImages(true);
const function1 = () =>
images.forEach((c, i) => setTimeout(() => setImage(c), i * 2000));
function1();
setTimeout(() => {
setShowImages(false);
setShowQuestions(true);
}, images.length * 2000);
}, [])
Here's a codesandbox link https://codesandbox.io/s/wizardly-elion-4dh35s?file=/src/App.js
CodePudding user response:
for a quick solution, you can do like that https://codesandbox.io/s/romantic-paper-bzknn8
useEffect(() => {
const function1 = () =>
images.forEach((c, i) =>
setTimeout(() => {
setImage(c);
if (i == 3) {
setShowImages(false);
setShowQuestions(true);
}
}, i * 2000)
);
function1();
//setShowImages(false);
}, []);
CodePudding user response:
Try This!
useEffect(() => {
const function1 = () => {
let timer = 0;
images.forEach((c, i) => {
timer ;
setTimeout(() => setImage(c), i * 2000);
});
setTimeout(() => {
setShowImages(false);
setShowQuestions(true);
}, timer * 2000);
};
function1();
}, []);
CodePudding user response:
One simple way is to keep the showQuestions logic once the last image is loaded.
const function1 = () =>
images.forEach((c, i) => {
setTimeout(() => {
setImage(c)
if(i == images.length - 1) {
setTimeout(() => {
setShowImages(false);
setShowQuestions(true);
}, 1000)
}
}, i * 2000)
});
You can also try simple wrapper logic with promise.
useEffect(() => {
const function1 = () =>
new Promise(res => {
images.forEach((c, i) => setTimeout(() => {
setImage(c);
if(i === images.length - 1) {
res();
}
}, i * 2000));
});
function1().then(() => {
setTimeout(() => {
setShowImages(false);
setShowQuestions(true)
}, 2000)
});
}, []);