Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Check out the different branches to see how this repo evolved over a week of Rea

- (main) React components & props
- (react-state) React state with useState & useEffect
- (react-lifting-state) React lifting state
- (react-router) Reacter router

You can see the changes from day to day in the ["Pull Requests"](https://github.com/TechmongersNL/fs04-react/pulls) in this repo

Expand Down
39 changes: 39 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"axios": "^1.6.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.21.3",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
Expand Down
4 changes: 4 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@
transform: rotate(360deg);
}
}

.background-blue {
background-color: rgb(232, 241, 244);
}
19 changes: 16 additions & 3 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
import "./App.css";
import CharacterList from "./components/character-list";
import CharacterListPage from "./pages/character-list-page";
import { Route, Routes } from "react-router-dom";
import HomePage from "./pages/home-page";
import CharacterDetailPage from "./pages/character-detail-page";
// import something from 'some place'

// App.js is the entry point to the rest of your app
// You can see how this behavior is set up in src/index.js
// This is default behavior for create-react-app
function App() {
return (
<div className="App">
{/* Now have a new CharactersList component, to keep our App component more clean and organized */}
<CharacterList />
<div className={"background-blue"}>
Here is a header that appears above every page
</div>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/characters" element={<CharacterListPage />} />
<Route path="/characters/:id" element={<CharacterDetailPage />} />
</Routes>
<div className={"background-blue"}>
Here is a footer that appears below every page
</div>
</div>
);
}
Expand Down
15 changes: 9 additions & 6 deletions src/components/character.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// You can import other components and use them too!
import Counter from "./counter";
import Image from "./image";
import { Link } from "react-router-dom";

// A React component is just a function that returns some JSX
// Specifically, it returns some JSX with only one parent element
Expand All @@ -14,12 +15,6 @@ const Character = (props) => {
return (
<>
<h1>{props.name}</h1>
<h2>Blood type</h2>
<p>{props.blood}</p>
<h2>Birthday</h2>
<p>{props.birthday}</p>
<h2>Quote</h2>
<p>{props.quote}</p>
{/* using a component within a component also works! */}
<Image url={props.imgUrl} />
{/* Passing props from CharacterList even further down into Counter */}
Expand All @@ -28,6 +23,14 @@ const Character = (props) => {
increaseLikes={props.increaseLikes}
id={props.id}
/>
{/* Link to /characters/1 if we're looking at Luna with id 1 */}
{/* Link to /characters/2 if we're looking at the second character with id 2 */}
{/* ...etc */}
{/* Then this will get matched to a Route defined in App.js */}
{/* You should never have a colon (:) in your Link "to" */}
<Link to={`/characters/${props.id}`}>
Go to {props.name}'s detail page
</Link>
<hr />
</>
);
Expand Down
1 change: 0 additions & 1 deletion src/components/counter.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const Counter = (props) => {
>
Increase likes
</button>
<hr />
<button onClick={favoriteClicked}>
{favorite ? "Un-favorite" : "Favorite"}
</button>
Expand Down
17 changes: 10 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById('root'));
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);

Expand Down
47 changes: 47 additions & 0 deletions src/pages/character-detail-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useParams } from "react-router-dom";
import axios from "axios";
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";

const CharacterDetailPage = () => {
// Get the value out of the path
// The useParams hook will get the variable named in your Route in your App.js
// useParams will that path variable in an object that we save into our own params variable
// I expect this to be the id of the character whose details we want to see
const params = useParams();
console.log(params);

const [characterDetailInfo, setCharacterDetailInfo] = useState(null);

// Get the characters detail data from the API
// Use the params object from above to get details for one specific character
const getCharacterDetail = async () => {
const response = await axios.get(
`https://my-json-server.typicode.com/TechmongersNL/fs03-react/characters/${params.id}`
);

console.log("response:", response.data);
setCharacterDetailInfo(response.data);
};

useEffect(() => {
getCharacterDetail();
}, []);

return characterDetailInfo ? (
<div>
<Link to="/characters">Go back to character list</Link>
<h1>{characterDetailInfo.name}</h1>
<h2>Blood type</h2>
<p>{characterDetailInfo.blood}</p>
<h2>Birthday</h2>
<p>{characterDetailInfo.born}</p>
<h2>Quote</h2>
<p>{characterDetailInfo.quote}</p>
</div>
) : (
"Loading..."
);
};

export default CharacterDetailPage;
13 changes: 13 additions & 0 deletions src/pages/character-list-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Link } from "react-router-dom";
import CharacterList from "../components/character-list";

const CharacterListPage = () => {
return (
<div>
<Link to={"/"}>Go back to Home Page</Link>
<CharacterList />
</div>
);
};

export default CharacterListPage;
12 changes: 12 additions & 0 deletions src/pages/home-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Link } from "react-router-dom";

const HomePage = () => {
return (
<>
<h1>Home Page</h1>
<Link to={"/characters"}>Go to Character List page</Link>
</>
);
};

export default HomePage;