Skip to content
Advertisement

How can I get the updated data without refresh the page in React?

I have a component with create a blog. It works fine and navigates me to the home after adding the new blog object in the database, but I have to refresh the page to be able to see the updated data. So how can I see the updated blogs after navigation without refreshing the page?

import { useState } from "react";
import { useNavigate } from "react-router-dom";

export const Create = () => {
  const [title, setTitle] = useState("");
  const [body, setbody] = useState("");
  const [author, setAuthor] = useState("mario");
  const [isPending, setPending] = useState(false);
  const nav = useNavigate();

  const newBlog = { title, body, author };

  const handelSubmit = (e) => {
    e.preventDefault();
    console.log(title);
    console.log(body);
    console.log(author);

    setPending(true);

    fetch("http://localhost:3001/blogs", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(newBlog),
    }).then(() => {
      console.log("newBlog Added");

      setPending(false);

      nav("/");
    });
    console.log(newBlog);
  };

  return (
    <div className="create">
      <h2>Add a New Blog</h2>
      <form onSubmit={handelSubmit}>
        <label htmlFor="">Blog title:</label>
        <input
          type="text"
          required
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <label htmlFor="">Blog Body:</label>
        <textarea
          required
          value={body}
          onChange={(e) => setbody(e.target.value)}
        ></textarea>

        <label htmlFor="">Blog author:</label>
        <select value={author} onChange={(e) => setAuthor(e.target.value)}>
          <option value="mario">Mario</option>
          <option value="magdy">Magdy</option>
        </select>
        {!isPending && <button>Add Blog</button>}
        {isPending && <button disabled>Adding Blog</button>}
      </form>
    </div>
  );
};

//Home component implementation
import React from "react";
import Blog from "./../blog/Blog";

export const Home = () => {
  // const { data, flag, error } = useFetch("http://localhost:3001/blogs");
  const [blogs, setBlogs] = useState(null);
  const [flag, setFlag] = useState(true);
  const [error, setError] = useState(null);


  useEffect(() => {
    fetch("http://localhost:3001/blogs")
      .then((res) => {
        if (!res.ok) {
          throw Error("Error in the API");
        }
        return res.json();
      })
      .then((data) => {
        console.log(data);
        setBlogs(data);
        setFlag(!flag);
      })
      .catch((e) => {
        console.log(e.message);
        setError(e.message);
        setFlag(!flag);
      });
    return () => {};
  }, []);

  return (
    <div className="home">
      {blogs && <Blog blogs={blogs} title="All Blogs" />}
      {flag && <p>Loading...</p>}
      {error !== null && <p>{error}</p>}
    </div>
  );
};
 

//Blog component implementation

import React from "react";
import { Link, Route, Routes } from "react-router-dom";
import { BlogDetails } from "../BlogDetails/BlogDetails";
import { Create } from "../create/Create";

import { Error } from "../Notfound/Error";

function Blog({ blogs, title }) {

  return (
    <Routes>
      <Route
        path="/"
        element={
          <div>
            <h2>{title}</h2>
            {blogs.map((blog) => {
              return (
                <div className="blog" key={blog.id}>
                  <Link to={`blogs/${blog.id}`}>
                    <h3>{blog.title}</h3>
                    <p>{blog.body}</p>
                    <h6>Written By {blog.author}</h6>
                  </Link>
                </div>
              );
            })}
          </div>
        }
      ></Route>
      <Route path="/create" element={<Create />}></Route>
      <Route path="/blogs/:id" element={<BlogDetails />}></Route>
      <Route path="*" element={<Error />}></Route>
    </Routes>
  );
}

export default Blog;

Advertisement

Answer

In order to update the blogs state, which is declared at the main point of the application, which is, for example, App.jsx, you must pass the state blogs and the set-state-action setBlogs as properties to the child component. For example:

The state in App.jsx:

const [blogs, setBlogs] = useState(null)

The child component (on which you will update the blogs state):

<Create blogs={blogs} setBlogs={setBlogs} />

On the fetch‘s then

fetch("http://localhost:3001/blogs", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(newBlog),
}).then((data) => {
  console.log("newBlog Added");

  setPending(false);
  setBlogs([...blogs, newBlog])

  nav("/");
});
console.log(newBlog);
Advertisement