Open lisavanmansom opened 1 month ago
React (ook wel React.js of ReactJS genoemd) is een Javascriptbibliotheek om gebruikersinterfaces mee te bouwen. React werd in 2011 door Meta ontwikkeld vanuit de behoefte om de code van grote webapplicaties beter beheersbaar te maken. Het was in eerste instantie een intern project en werd gebruikt voor het Facebook- en Instagramplatform. In 2013 introduceerde Meta React aan het publiek en maakte er een opensourceproject van. Sindsdien groeit het gebruik van React en wordt de bibliotheek door meer dan één miljoen websites gebruikt, waaronder grote namen als Netflix en Uber. React wordt op GitHub onderhouden door Meta en een community van individuele ontwikkelaars en bedrijven.
React has been designed from the start for gradual adoption. You can use as little or as much React as you need. Whether you want to get a taste of React, add some interactivity to an HTML page, or start a complex React-powered app, this section will help you get started.
npx create-react-app my-app
cd my-app
npm start
When you’re ready to deploy to production, running npm run build
will create an optimized build of your app in the build folder.
npx (runner tool):
npx create-react-app my-app
npm:
npm init react-app my-app
yarn:
yarn create react-app my-app
While NPM is used as a package manager, NPX, on the other hand, is used to execute Javascript packages.
NPM stands for Node Package Manager. It is a Javascript package manager and the default package manager for Node projects. NPM is installed when NodeJS is installed on a machine. NPX stands for Node Package eXecute. It is simply an NPM package runner. It allows developers to execute any Javascript Package available on the NPM registry without even installing it. NPX is installed automatically with NPM version 5.2.0 and above.
NPM is a package manager used to install, update or remove packages and dependencies your project requires. NPX is an NPM package used to execute any package on the NPM registry directly without installing it.
After creation, your project should look like this:
my-app/
README.md
node_modules/
package.json
public/
index.html
favicon.ico
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg
For the project to build, these files must exist with exact filenames:
public/index.htm
l is the page template;src/index.js
is the JavaScript entry point.You can delete or rename the other files. You may create subdirectories inside src
. For faster rebuilds, only files inside src are processed by webpack. You need to put any JS and CSS files inside src
, otherwise webpack won’t see them.
After creation, your project should look like this:
my-app/
README.md
node_modules/
package.json
public/
index.html
favicon.ico
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg
For the project to build, these files must exist with exact filenames:
public/index.htm
l is the page template;src/index.js
is the JavaScript entry point.You can delete or rename the other files. You may create subdirectories inside src
. For faster rebuilds, only files inside src are processed by webpack. You need to put any JS and CSS files inside src
, otherwise webpack won’t see them.
BrowserRouter
Routes
: Replaces the older Switch
component in react-router-dom v6. It looks through its children Route
elements and renders the first one that matches the current URL. Route
: Defines a mapping between a URL path and a component to render.Using react-router-dom makes it straightforward to create multi-page React applications with dynamic routing capabilities. You can set up a robust navigation system that enhances the user experience without full page reloads.
npm install react-router-dom
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.27.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
import React from 'react';
const introductionT1 = () => {
return (
<div>
<h2>introduction1</h2>
</div>
);
};
export default introductionT1;
Is there a recommended way to structure React projects? React doesn’t have opinions on how you put files into folders. That said there are a few common approaches popular in the ecosystem you may want to consider.
One common way to structure projects is to locate CSS, JS, and tests together inside folders grouped by feature or route.
common/
Avatar.js
Avatar.css
APIUtils.js
APIUtils.test.js
feed/
index.js
Feed.js
Feed.css
FeedStory.js
FeedStory.test.js
FeedAPI.js
profile/
index.js
Profile.js
ProfileHeader.js
ProfileHeader.css
ProfileAPI.js
folder structure:
intro-task/
task1.js
task2.js
task3.js
task4.js
task.css
task.test.js
task.js example:
import './task.css';
import React from 'react';
import { Link } from 'react-router-dom';
function Task2() {
return (
<div>
<h1>Task 2 Page</h1>
<Link to="/task1">Go to Task 1</Link>
<Link to="/task3">Go to Task 3</Link>
</div>
);
}
export default Task2;
task.test.js
import { render, screen } from '@testing-library/react';
import Task1 from './task1';
import Task2 from './task2';
import Task3 from './task3';
import Task4 from './task4';
test('renders learn react link', () => {
render(<>
<Task1/>
<Task2/>
<Task3/>
<Task4/>
</>);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
Instead of downloading the entire app before users can use it, code splitting allows you to split your code into small chunks which you can then load on demand. Code-splitting your app can help you “lazy-load” just the things that are currently needed by the user, which can dramatically improve the performance of your app. While you haven’t reduced the overall amount of code in your app, you’ve avoided loading code that the user may never need, and reduced the amount of code needed during the initial load.
A good place to start is with routes. Most people on the web are used to page transitions taking some amount of time to load. You also tend to be re-rendering the entire page at once so your users are unlikely to be interacting with other elements on the page at the same time.
Here’s an example of how to setup route-based code splitting into your app using libraries like React Router with React.lazy.
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Suspense>
</Router>
);
The React.lazy function lets you render a dynamic import as a regular component. React.lazy takes a function that must call a dynamic import(). This must return a Promise which resolves to a module with a default export containing a React component. The lazy component should then be rendered inside a Suspense component, which allows us to show some fallback content (such as a loading indicator) while we’re waiting for the lazy component to load.
import React, { Suspense } from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
1. SWR method
This method is used to fetch data from a server and is used in React. It manages any issues that may arise when obtaining the data and helps you manage its storage. SWR includes useState() and useEffect(), so there is no need to import them.
The advantages of SWR:
How to use SWR to get data:
npm i swr
2. JavaScript Fetch() method
The fetch() method is well-known for retrieving data from APIs. It is recognized as the simplest and most used approach.
The advantages of using the fetch() method:
How to use fetch() to get data:
Inside useEffect(), we fetch our data by sending a request with the API key. The response comes back in JSON (JavaScript Object Notation).
In the return statement, we process the received photos by utilizing a map() function to iterate through each item.
In our specific scenario, we are only interested in the photos. We render them in the browser by displaying them in the main file of the application, or root. The main file could be App.jsx or Index.js.
Om data te fetchen maak ik gebruik van een Fetch.jsx
component, hier fetch ik data van de API en worden daar article's van gemaakt. Om een taak te renderen maak ik gebruik van map
die de task state overschrijft (an array of task object). Ik render de title en de description in de article, voor beide maak ik gebruik van dangerouslySetInnerHTML
omdat het in html format is gezet in Directus.
import { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
const Fetch = () => {
const [Tasks, setTasks] = useState([]);
useEffect(() => {
fetch('https://fdnd-agency.directus.app/items/dropandheal_task')
.then((res) => res.json())
.then((data) => {
console.log(data);
setTasks(data.data);
});
}, []);
return (
<section>
{Tasks.map((task) => (
<article key={task.id}>
<h3>{task.title}</h3>
<p dangerouslySetInnerHTML={{ __html: task.description }} />
<Link to={`/task/${task.id}`}>View Details</Link> {/* Link to task detail page */}
</article>
))}
</section>
);
}
export default Fetch;
De App.jsx regelt de routing.
import './App.css';
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { Link } from 'react-router-dom';
import TaskDetail from './intro-task/taskDetail';
function App() {
return (
<div className="App">
<h1>Drop & Heal</h1>
<Link to="/task/1">Introductie Rouwtaken</Link>
<Routes>
<Route path="/task/:id" element={<TaskDetail />} />
</Routes>
</div>
);
}
export default App;
In de TaskDetail geef ik custom elementen mee aan de taken, dit doe ik door gebruik te maken van id === '2' &&
. Hierdoor wordt gecheckt of de huidige id bij de huidige taak hoort en daarna worden de custom elementen gerendeerd als het true
is. Elke taak staat op een aparte pagina.
import MeshgradBlue from '../components/Meshgrad-blue.jsx';
import MeshgradRed from '../components/Meshgrad-red.jsx';
import MeshgradGreen from '../components/Meshgrad-green.jsx';
import MeshgradPink from '../components/Meshgrad-pink';
import ArrowR from '../components/ArrowR.jsx';
import ArrowL from '../components/ArrowL.jsx';
import './task.css';
import { useState, useEffect } from 'react';
import { useParams, Link } from 'react-router-dom';
const TaskDetail = () => {
const { id } = useParams();
const [task, setTask] = useState(null);
useEffect(() => {
fetch(`https://fdnd-agency.directus.app/items/dropandheal_task/${id}`)
.then((res) => res.json())
.then((data) => {
setTask(data.data);
});
}, [id]);
if (!task) {
return <div>Loading...</div>; // Loading state aanpassen
}
return (
<section>
<h1>Introductie rouwtaken</h1>
<h2>Rouwtaak</h2>
<h3>{task.title}</h3>
<div dangerouslySetInnerHTML={{ __html: task.description }} />
{/* custom elements based on id */}
{id === '1' && (
<div className={`task-detail task-${id}`}>
<MeshgradBlue />
<Link to="/task/1"><ArrowL /></Link>
<Link to="/task/2"><ArrowR /></Link>
<div aria-busy="true" aria-describedby="progress-bar"></div>
<progress value="50" max="100"></progress>
</div>
)}
{id === '2' && (
<div className={`task-detail task-${id}`}>
<MeshgradRed />
<Link to="/task/1"><ArrowL /></Link>
<Link to="/task/3"><ArrowR /></Link>
<div aria-busy="true" aria-describedby="progress-bar"></div>
<progress value="60" max="100"></progress>
</div>
)}
{id === '3' && (
<div className={`task-detail task-${id}`}>
<MeshgradGreen />
<Link to="/task/2"><ArrowL /></Link>
<Link to="/task/4"><ArrowR /></Link>
<div aria-busy="true" aria-describedby="progress-bar"></div>
<progress value="70" max="100"></progress>
</div>
)}
{id === '4' && (
<div className={`task-detail task-${id}`}>
<MeshgradPink/>
<Link to="/task/3"><ArrowL /></Link>
<Link to="/task/4"><ArrowR /></Link>
<div aria-busy="true" aria-describedby="progress-bar"></div>
<progress value="80" max="100"></progress>
</div>
)}
</section>
);
};
export default TaskDetail;
Case study React
In deze issue documenteer ik mijn bevindingen van react en staan voorbeelden hoe ik dat heb uitgewerkt. In deze issue staat o.a QuickStart React, mappenstructuur en code splitting.
bronnen lijst: