React JS
https://react.dev/learn/start-a-new-react-project
npx create-next-app@latest
npx create-react-app@latest {project name}
Create Project
C:\react-js>npx create-react-app@latest my-app
Run
C:\react-js\my-app> npm start
npm i react-router-dom
https://www.npmjs.com/package/react-router-dom
Install React SWR:
npm i swr
https://www.npmjs.com/package/swr
src\App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //src\App.js import { BrowserRouter, Routes, Route } from "react-router-dom" ; //npm i react-router-dom https://www.npmjs.com/package/react-router-dom import Home from "./elements/Home" ; import PostList from "./elements/PostList" ; import PostDetails from "./elements/PostDetails" ; function App() { return ( <BrowserRouter> <Routes> <Route path= "/" element={<Home />} /> <Route path= "/postswr" element={<PostList />} /> <Route path= "/post-detail/:postId" element={<PostDetails />} /> </Routes> </BrowserRouter> ); } export default App; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | //src\elements\Home.js import React from 'react' ; import Posts from './Posts' import { Suspense } from "react" ; function Home() { return ( <div className= "w-screen py-20 flex justify-center flex-col items-center" > <div className= "flex items-center justify-between gap-1 mb-5" > <h1 className= "text-4xl font-bold" >Basic example fetch dummy data</h1> </div> <div className= "overflow-x-auto py-10" > <Suspense fallback= "Loading..." > <Posts/> </Suspense> </div> </div> ) } export default Home |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | //src\elements\Posts.js import { useEffect, useState } from "react" ; function Post() { const [posts, setPosts] = useState([]); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); useEffect(() => { const fetchData = async (url) => { setIsLoading(true); try { const data = await fetch(base_url + url) .then(res => res.json()); setPosts(data ? data.posts : []); } catch (error) { setError( 'Failed to load' ); } setIsLoading(false); } fetchData( '/posts' ); }, []); return ( <div className= 'w-1/2 py-10 m-auto flex justify-between items-center align-middle flex-wrap gap-10' > { error ? <div>{error}</div> : null } { isLoading ? <div>loading...</div> : null } { posts ? posts.map(post => { return ( <div key={post.id} className= 'btn-primary p-2 bg-blue-500 text-white text-lg rounded-lg hover:shadow-lg disabled:opacity-50' > <h3><a>{post.title}</a></h3> <p>{post.body}</p> <span>Views: {post.views}</span> <div>Tags: {post.tags.map(tag => <span key={tag}>{tag}</span>)}</div> </div> ) }) : null } </div> ); } export default Post; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | //src\elements\PostList.js import React from "react" ; import { Link } from "react-router-dom" ; function PostList() { const fetcher = (url) => { return fetch(base_url + url).then(res => res.json()); }; const { data, error, isLoading } = useSWR( '/posts' , fetcher); const style = {margin: '2px' , background: '#000000' , padding: '2px 7px' , borderRadius: '6px' }; return ( <div className= "w-screen py-20 flex justify-center flex-col items-center" > <div className= "flex items-center justify-between gap-1 mb-5" > <h1 className= "text-4xl font-bold" >React.js Data Fetching With React SWR</h1> </div> <div className= "overflow-x-auto py-1" > <div className= 'w-1/2 py-10 m-auto flex justify-between items-center align-middle flex-wrap gap-10' > { error ? <div>failed to load</div> : null } { isLoading ? <div>loading...</div> : null } { data ? data.posts.map(post => { return ( <div key={post.id} className= 'btn-primary p-2 bg-blue-500 text-white text-lg rounded-lg hover:shadow-lg disabled:opacity-50' > <h3><Link to={`/post-detail/${post.id}`}>{post.title}</Link></h3> <p>{post.body}</p> <span>Views: {post.views}</span> <div>Tags: {post.tags.map(tag => <span key={tag} style={style}>{tag}</span>)}</div> </div> ) }) : null } </div> </div> </div> ) } export default PostList |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | //src\elements\PostDetails.js import React from "react" ; import { useParams } from 'react-router-dom' ; import useSWR from 'swr' ; function PostDetails() { let { postId } = useParams(); const fetcher = async ([url, postId]) => { const res = await fetch(base_url + url + `/${postId}`); if (!res.ok) { const error = new Error( 'An error occurred while fetching the data.' ) error.status = res.status throw error } return res.json() } const { data: post, error, isLoading } = useSWR([ '/posts' , postId], fetcher); const style = {margin: '2px' , background: '#d7d4d4' , padding: '2px 7px' , borderRadius: '6px' }; return ( <div className= 'w-1/2 py-10 m-auto flex justify-between items-center align-middle flex-wrap gap-10' > { error ? <div>{error.message}</div> : null } { isLoading ? <div>loading...</div> : null } { post && ( <div className= 'btn-primary p-2 bg-blue-500 text-white text-lg rounded-lg hover:shadow-lg disabled:opacity-50' > <h3>{post.title}</h3> <p>{post.body}</p> <span>Views: {post.views}</span> <div>Tags: {post.tags.map(tag => <span key={tag} style={style}>{tag}</span>)}</div> <div>Likes: 👍 {post.reactions.likes}</div> <div>Deslikes: 👎 {post.reactions.likes}</div> </div> ) } </div> ) } export default PostDetails; |
http://localhost:3000/