Attempting to build a flashcard app with React and React Hooks, I am able to get my home screen rendered. When introducing Router, I am able to click the link, update the path to be the one I am looking for, but nothing is being rendered from that new page.
App.js
import React, {useState, useEffect} from "react";
import Header from "./Header";
import NotFound from "./NotFound";
import ShowAllDecks from './ShowAllDecks';
import axios from 'axios';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
function Layout() {
const [flashcards, setFlashcards] = useState([])
//Delete a deck of flashcards
const deleteHandler = (id) => {
const result = window.confirm('Are you sure you want to delete?');
if (result) {
setFlashcards(flashcards.filter(deck => deck.id !== id));
};
};
useEffect(() => {
axios
.get('http://localhost:5000/decks?_embed=cards')
.then(res => {
setFlashcards(res.data.map((questionItem, index) => {
return {
id: `${index}-${Date.now()}`,
name: questionItem.name,
description: questionItem.description,
cards: questionItem.cards.length,
}
}))
})
}, [])
return (
<div>
<Header />
<Router>
<Switch>
<Route exact={true} path={'/'}>
<ShowAllDecks flashcards={flashcards} setFlashcards={setFlashcards} deleteHandler={deleteHandler} />
</Route>
</Switch>
</Router>
<NotFound />
</div>
)
}
ShowAllDecks.js --> List of flashcard decks
import React from 'react';
import Deck from './Deck';
import ViewDeck from './ViewDeck';
function ShowAllDecks({ flashcards, deleteHandler }) {
return (
<div className='container'>
<button>Create New</button>
{flashcards.map((flashcard) => {
return (
<Deck flashcards={flashcards} flashcard={flashcard} key={flashcard.id} deleteHandler={deleteHandler} />
)
})}
</div>
)
}
export default ShowAllDecks;
Deck.js --> Individual deck of flashcards
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import ViewDeck from './ViewDeck';
function Deck({ flashcard, flashcards, setFlashcards, deleteHandler}) {
return (
<div className='container'>
<div className='card'>
<div className='card-body'>
<h3 className='card-title'>{flashcard.name}</h3>
<p className='card-text'>{flashcard.description}</p>
<p className='card-text'>{flashcard.cards} cards</p>
<Link to={`decks/${flashcard.id}`}>View</Link>
<button>Study</button>
<button onClick={() => deleteHandler(flashcard.id)}><i className="fas fa-trash" /></button>
</div>
<Router>
<Switch>
<Route exact={true} path={`decks/${flashcard.id}`}>
<ViewDeck flashcards={flashcards} flashcard={flashcard} deleteHandler={deleteHandler} />
</Route>
</Switch>
</Router>
</div>
</div>
)
}
export default Deck;
ViewDeck.js --> Should be a new screen for individual flashcard deck where I can view the list of cards in the deck, edit the cards, or add new cards.
import React from 'react';
function ViewDeck({ flashcards, flashcard, deleteHandler }) {
console.log(flashcards)
return (
<p>{flashcards.name}</p>
)
}
export default ViewDeck;
When on the index route, flashcards is an array of objects and flashcard is a deck of cards object. What am I doing wrong with my Routes or components that make my component not render?
Example of the URL:
[
{
"id": 1,
"name": "Rendering in React",
"description": "React's component structure allows for quickly building a complex web application that relies on DOM manipulation. ",
"cards": [
{
"id": 1,
"front": "Differentiate between Real DOM and Virtual DOM.",
"back": "Virtual DOM updates are faster but do not directly update the HTML",
"deckId": 1
},
{
"id": 2,
"front": "How do you modify the state of a different React component?",
"back": "Not at all! State is visible to the component only.",
"deckId": 1
},
{
"id": 3,
"front": "How do you pass data 'down' to a React child component?",
"back": "As properties or props",
"deckId": 1
},
{
"cards": [],
"front": "b",
"back": "b",
"deckId": 1,
"id": 7
}
]
}
]