Lag en React App med WordPress REST Api
Lag en React App med WordPress REST Api
av Ole Petter den 17. januar 2021
Sist oppdatert: 17 januar, 2021 kl 17:27Contents
Start en ny React App
I et tidligere innlegg har jeg vist hvordan man kan opprette en react-app enkelt med node.js og create-react-app.
npx create-react-app my-app
cd my-app
npm start
Lage routes
For å håndtere ulike innleggssider, brukes ‘react-router-dom’. Den inneholder komponenter som BrowserRouter, Switch og Route, som gjør at man kan navigere rundt i en Single Page Application.
App.js
import './App.css';
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Header from './components/Header/Header';
import PostsPage from './pages/PostsPage';
import SinglePostPage from './pages/SinglePostPage';
function App() {
return (
<BrowserRouter>
<Header />
<Switch>
<Route path="/" exact>
<PostsPage />
</Route>
<Route path="/posts/:id" exact>
<SinglePostPage />
</Route>
</Switch>
</BrowserRouter>
);
}
export default App;
Lage Posts.js og SinglePost.js
Posts.js skal hente inn innlegg fra wordpress, og de blir automatisk sortert etter dato.
Posts.js
import React, { useEffect, useState } from 'react'
import { fetchPosts } from '../../api';
import PostListTemplate from './templates/PostListTemplate';
function Posts() {
const [posts, setPosts] = useState([])
const [page, setPage] = useState(1);
const [perPage, setPerPage] = useState(10);
useEffect(() => {
async function getPosts() {
const data = await fetchPosts(page, perPage);
if (data?.length > 0) {
if (page > 1) {
setPosts(posts.concat(data))
} else {
setPosts(data);
}
}
}
getPosts()
}, [page, perPage])
return (
<div>
<div className="row">
{posts?.map((post, index) => {
return <PostListTemplate key={index} post={post} />
})}
</div>
<button className="btn btn-block btn-primary" onClick={() => setPage(page => page + 1)}>Load more</button>
</div>
)
}
export default Posts
SinglePost.js
import React, { useEffect, useState } from 'react'
import { fetchSinglePost } from '../../api'
import { formatDate } from '../../handlers/dateFormatter';
function SinglePost({id}) {
const [post, setPost] = useState()
useEffect(() => {
async function getPost() {
const data = await fetchSinglePost(id);
if (data) {
setPost(data)
}
}
getPost()
}, [id])
return (
<div>
<h2>{post?.title?.rendered}</h2>
<div>
<p><small> Av {post?._embedded?.author[0]?.name} den {formatDate(post?.date)}</small></p>
</div>
<div className="my-4">
<img src={post?.fimg_url} alt="" className="img-fluid" />
</div>
<hr />
<div dangerouslySetInnerHTML={{__html: post?.content?.rendered}} />
</div>
)
}
export default SinglePost
Håndtere API kall til REST Api
For å hente inn data fra WordPress sin REST Api må man bruke XHR, eller den mer moderne fetch API som støttes av moderne nettlesere.
For å håndtere API-kall oppretter jeg en egen fil kalt api.js i src-mappen.
api.js
const BASE_URL = "https://progitek.no"
export async function fetchPosts(page=1, perPage=10) {
let data = []
try {
const response = await fetch(`${BASE_URL}/wp-json/wp/v2/posts?page=${page}&per_page=${perPage}&_embed`);
data = await response.json();
} catch (error) {
}
return data
}
export async function fetchSinglePost(id) {
let data
try {
const response = await fetch(`${BASE_URL}/wp-json/wp/v2/posts/${id}?_embed`);
data = await response.json();
} catch (error) {
}
return data
}
Formatere dato
I src-mappen oppretter jeg en ny mappe kalt «handlers». I denne mappen oppretter jeg en fil kalt «dateFormatter.js». Denne håndterer datoformatering.
dateFormatter.js
export function formatDate(date) {
const dateObj = new Date(date);
const day = dateObj.getDate();
const month = dateObj.getMonth();
const year = dateObj.getFullYear();
const dateFormatted = `${day}/${month}/${year}`
return dateFormatted
}
Opprette sider for innlegg
For å få bedre oversikt over de ulike sidene, er det greit å opprette en mappe kalt «pages», hvor man samler alle komponentene som brukes til å genrere sider, eller routes.
PostsPage.js
import React from 'react'
import Posts from '../components/Blog/Posts'
function PostsPage() {
return (
<div className="container my-4">
<Posts />
</div>
)
}
export default PostsPage
SinglePostPage.js
import SinglePost from '../components/Blog/SinglePost'
function SinglePostPage() {
const {id} = useParams()
return (
<div className="container my-4">
<SinglePost id={id} />
</div>
)
}
export default SinglePostPage