all I am trying to do where to put generateQuestion
function and if I put it in App.js
how to pass props form App.js
to Quiz.js
please if you have a better implementation of routing & generateQuestion
function feel free to leave your recommendations
CodePudding user response:
The generateQuestion
callback is asynchronous, so you won't be able to send data in route state via the Link
, but what you can do is move the onClick
handler to the Link
and call event.preventDefault
on the click
event to prevent the navigation action, and issue an imperative navigation after the questions have been fetched.
Example:
import { Link, useNavigate } = 'react-router-dom';
...
const navigate = useNavigate();
...
generateQuestions = async (event) => {
event.preventDefault();
try {
const data = await questionsData();
const arrData = data.map(element => ({
...element,
id: nanoid(),
}));
navigate("/quiz", { state: { questions: arrData } });
} catch(error) {
// handle rejected Promise/error/etc...
}
}
...
<Link to="/quiz" onClick={generateQuestions}>
<button type="button">
Start Quiz
</button>
</Link>
...
In the Quiz
component use the useLocation
hook to access the passed route state.
import { useLocation } from 'react-router-dom';
...
const { state } = useLocation();
const { questions } = state || {};
CodePudding user response:
Your aren't able to pass data between siblings. So, you can do one of two things, you can either create Context which surrounds your whole app and provides data to all components in your app, or you can pull data into your index.js. But I would recommend Context over the latter. You would implement it like so:
import React, { useState } from 'react'
const GameContext = React.createContext()
function GameContextProvider(props) {
const [data, setData] = useState()
const getGameData = (data) => {
setData(data)
}
return (
<GameContext.Provider value={{ data, getGameData }}>
{props.children}
</GameContext.Provider>
)
}
export { GameContext, GameContextProvider }
then you wrap your app with GameContextProvider
<GameContextProvider>
<App />
</GameContextProvider>
Now your app has access to data. This was a very simple demo, so you will have to change quite a bit to make this work, but this is what you would need to do to share state between siblings, this or pull state into the parent which in your case would be index.js