Reputation: 430
The structure of my application is :
When the user clicks on StartQuiz button in<Home>
component,he is directed to the '/quiz'
route. <Quiz>
component is rendered after that.
My <Quiz>
component is supposed to get the questions from the App component but is not getting that. <App>
component gets the questions from the <Home>
Component..
The Code is as follows:
Home.js file:
import ErrorMessage from '../errormessage';
const Home = (props) => {
const {name,setName,fetchQuestions}=props;
const [category,setCategory]=useState("");
const [difficulty,setDifficulty]=useState("");
const [error,setError]=useState(false);
const history=useNavigate();
const handlesubmit=()=>{
if(!category || !name || !difficulty)
setError(true);
else
{
fetchQuestions(category,difficulty);
history('/quiz') //pushes it in the quiz route
}
}
return (
<div className="content">
<div className="settings">
<span style={{fontSize:30}}>Quiz Settings</span>
</div>
<div className="settingsselect">
{error && <ErrorMessage></ErrorMessage>}
<TextField label="Enter Your Name" variant="outlined" onChange={(e)=>setName(e.target.value)} value={name}/>
<TextField id="outlined-select-currency" select label="Select Category" variant="outlined" onChange={(e)=>setCategory(e.target.value)} value={category}>
{
Categories.map((cat)=>{
return(
<MenuItem key={cat.category} value={cat.value}>{cat.category}</MenuItem>);
})
}
</TextField>
<TextField select label="Select Difficulty" onChange={(e)=>setDifficulty(e.target.value)} value={difficulty}>
<MenuItem label="Easy" value="easy">Easy</MenuItem>
<MenuItem label="Medium" value="medium">Medium</MenuItem>
<MenuItem label="Hard" value="hard">Hard</MenuItem>
</TextField>
<Button variant="contained" color="primary" onClick={handlesubmit}>Start Quiz</Button>
</div>
<img src="question.svg" className="banner"></img>
</div>
);
};
export default Home;
App.js file:
const [questions,setQuestions]=useState();
useEffect(()=>{
console.log("Questions have changed");
},[questions]);
const fetchQuestions=async(category,difficulty)=>{
const {data}=await axios(`https://opentdb.com/api.php?amount=10&category=${category}&difficulty=${difficulty}&type=multiple`);
setQuestions(data.results);
}
return (
<BrowserRouter>
<div className="App" style={{backgroundImage: "url(./ques1.png)"}}>
<Header/>
<Routes>
<Route path="/home" exact element={<Home name={name} setName={setName} fetchQuestions={fetchQuestions}/>}></Route>
<Route path="/quiz" exact element={<Quiz name={name} questions={questions} score={score} setScore={setScore} />}></Route>
</Routes>
<Footer></Footer>
</div>
</BrowserRouter>
);
}
export default App;
Quiz.js file:
const Quiz = (props) => {
const {name,questions,score,setScore}=props;
const [options,setOptions]=useState();
const [currentQuestion,setCurrentQuestion]=useState(0);
return (
<div className='quiz'>
<span className="subtitle">Welcome ,{name}</span>
<div className="questionInfo">
<Question questions={questions} currentQuestion={currentQuestion} setCurrentQuestion={setCurrentQuestion} options={options}/>
</div>
</div>
);
};
export default Quiz;
But Im getting undefined
when doing console.log(questions)
in the <Quiz>
component..
please figure out the issue..
Upvotes: 2
Views: 1829
Reputation: 31862
When you call fetchQuestions(category,difficulty)
in handleSubmit
you need to await it there as well.
The await inside fetchQuestions
does not extend outside of the function, so making handleSubmit
async as well will properly await before navigating
// Home
const handlesubmit = async () => {
if(!category || !name || !difficulty) {
setError(true);
} else {
await fetchQuestions(category,difficulty);
history('/quiz')
}
}
Next, in Quiz you will need useState()
and useEffect()
to respond to the change of props.questions.
// Quiz
import React, {useState, useEffect} from 'react'
const Quiz = (props) => {
const [questionsDisplay, setQuestionsDisplay] = useState()
useEffect(() => {
const display = props.questions.map((q,idx) => (<div key={idx}>{q.question}</div>))
setQuestionsDisplay(display)
}, [props.questions])
return (
<div className='quiz'>
<span className="subtitle">Welcome ,{name}</span>
<div className="questionInfo">
{questionsDisplay}
</div>
</div>
);
};
export default Quiz;
Upvotes: 1