On the quizzes page, you want to list all all the quizzes that are available in the catalog. Since the catalog is an object rather than array, you use Object.values
to get an array of quizzes and then map that array into an array of list items:
import {quizzes} from './catalog';
export function Quizzes(props) {
return (
<div className="quiz-list">
<h2>Quizzes</h2>
<ol>
{Object.values(quizzes).map(quiz =>
<li key={quiz.slug}>{quiz.title}</li>
)}
</ol>
</div>
);
}
The slug is used as a unique identifier.
When you visit the quizzes page, you see the content run right up against the edge of the window. You add some spacing in App.css
:
.quiz-list {
margin: 20px;
}
You want each of the list items to be a link to the associated quiz. In the past, you've used anchor elements for links. Clicking on an anchor element would cause the browser to issue a GET
request to the web server, and the browser would then load the app afresh with the content it got back. In this case, your app is already fully downloaded; all its pages are in memory. Also, it probably has state that you don't want to lose when the new page is loaded. So, you want to avoid plain anchor elements.
The React Router library provides the alternative Link
component for making anchors that don't fire off a request to the web server and don't reload the page. You turn each quiz title into a Link
:
// ...
import {Link} from 'react-router-dom';
export function Quizzes(props) {
return (
<div className="quiz-list">
<h2>Quizzes</h2>
<ol>
{Object.values(quizzes).map(quiz =>
<li key={quiz.slug}>
<Link to={`/quiz/${quiz.slug}`}>{quiz.title}</Link>
</li>
)}
</ol>
</div>
);
}
The to
prop behaves much like the href
attribute of an anchor element. Clicking on a Link
sets the path of the window's current location to the to
value, but it does not make the browser fetch anything or replace the page. It does cause the app to re-render, however. Since the path has been modified since the last render, a different Route
will match and a different component will display.
Try clicking on a quiz. Do you see the URL in the browser's location bar change? Do you see the Quiz
component appear? What happens if you hit the browser's back button?
When the Quiz
component loads, you want to render the quiz whose slug is listed in the path. Extracting out the slug is a job for React Router's parameters feature.