Keith

React JS JSON Placeholder Posts Blog

by Keith Rowles • 01/05/2023React

Grey cement wall with white paint

Summary

A test blog website using JSON Placeholder posts API as the dummy datasource - add, delete and view posts.

This project has been deployed to Vercel.

Note: My localhost version of this application is running json server.

Tech and Tools

  • JavaScript
  • CSS
  • HTML
  • React JS
  • GitHub
  • Vercel

Sample Code

To view full source code please view GitHub repo. (Link below)

Home.js

import BlogList from './BlogList';
import useFetch from './useFetch';

const Home = () => {
  const {
    data: blogs,
    isPending,
    error,
  } = useFetch('https://jsonplaceholder.typicode.com/posts?_limit=10');
  // const {data: blogs, isPending, error} = useFetch('http://localhost:8000/blogs');

  return (
    <div className="home">
      {error && <div>{error}</div>}
      {isPending && <div>Loading...</div>}
      {blogs && <BlogList blogs={blogs} title="All Blog Posts" />}
    </div>
  );
};

export default Home;

App.js

import Navbar from './Navbar';
import Home from './Home';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Create from './Create';
import BlogDetails from './BlogDetails';
import NotFound from './NotFound';

function App() {
  return (
    <Router>
      <div className="App">
        <Navbar />
        <div className="content">
          <Switch>
            <Route exact path="/">
              <Home />
            </Route>
            <Route path="/create">
              <Create />
            </Route>
            <Route path="/blogs/:id">
              <BlogDetails />
            </Route>
            <Route path="*">
              <NotFound />
            </Route>
          </Switch>
        </div>
      </div>
    </Router>
  );
}

export default App;

Create.js

import { useState } from 'react';
import { useHistory } from 'react-router-dom';

const Create = () => {
  const [title, setTitle] = useState('');
  const [body, setBody] = useState('');
  const [author, setAuthor] = useState('bobby');
  const [isPending, setIsPending] = useState(false);
  const history = useHistory();

  const handleSubmit = (e) => {
    e.preventDefault();
    const blog = { title, body, author };

    setIsPending(true);

    fetch('https://jsonplaceholder.typicode.com/posts', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(blog),
    }).then(() => {
      console.log('New Blog Added');
      setIsPending(false);
      //history.go(-1);
      history.push('/');
    });
  };

  return (
    <div className="create">
      <h2>Add a New Blog Post</h2>
      <form onSubmit={handleSubmit}>
        <label>Blog Title: </label>
        <input
          type="text"
          required
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <label>Blog Body: </label>
        <textarea
          required
          value={body}
          onChange={(e) => setBody(e.target.value)}
        ></textarea>
        <label>Blog Author:</label>
        <select value={author} onChange={(e) => setAuthor(e.target.value)}>
          <option value="bobby">bobby</option>
          <option value="sammy">sammy</option>
          <option value="freddy">freddy</option>
        </select>
        {!isPending && <button>Add Blog Post</button>}
        {isPending && <button disabled>Adding Blog Post...</button>}

        {/* <p>{title}</p>
        <p>{body}</p>
        <p>{author}</p> */}
      </form>
    </div>
  );
};

export default Create;

Demo

Open demo on Vercel.

Link to Demo

Repo

Open GitHub Repository to view full source code.

Link to Repo