0

I'm trying to get the id from the URL, so I can get a specific post from the API, in order to return it. I can't use Class Component to do so, because useParams only works with functions. I try to put the data inside the variable post, but it also didn't work.

import { useParams } from "react-router-dom";
import axios from "axios";

const Post = () => {
    let params = useParams();
    let post = null;
    axios.get('https://jsonplaceholder.typicode.com/posts/' + params.post_id)
    .then(res => {
        post = res.data ? (
            <div>
                <h4>{res.data.title}</h4>
                <p>{res.data.body}</p>
            </div>
        ) : (
            <div>Loading post...</div>
        );
    });
    
    return (
        <div>{post}</div>
    )
}

export default Post

2 Answers 2

1

Dynamic data, like a request with axios should be done within a useEffect hook. With the dependencies array empty [] it provides that the request in the useEffect hook will only happen the first render, but not the following after.

When the response comes in, save the result in a state. Render the proper data based on the value of the state.

import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import axios from "axios";

const Post = () => {
  let params = useParams();
  const [post, setPost] = useState(null)

  useEffect(() => {
    axios.get('https://jsonplaceholder.typicode.com/posts/' + params.post_id)
      .then(post => {
        setPost(post)
      });
  }, [])
  
  return (
    <div>
      {post !== null ? (
        <div>
          <h4>{res.data.title}</h4>
          <p>{res.data.body}</p>
        </div>
      ) : (
        <div>Loading post...</div>
      )}
    </div>
  )
}

export default Post
Sign up to request clarification or add additional context in comments.

Comments

0

You should use useEffect and useState hooks in this way

import { useEffect, useState } from "react";
import axios from "axios";
import { useParams } from "react-router-dom";
import "./App.css";

function App() {
  let params = useParams();
  const [postState, setPostState] = useState({ data: {}, loading: false });

  useEffect(() => {
    axios.get("https://jsonplaceholder.typicode.com/posts/"+ params.post_id).then((res) => {
      if (res.data) {
        setPostState((s) => ({ ...s, data: res.data }));
      } else {
        setPostState((s) => ({ ...s, loading: true }));
      }
    });
  }, []);

  const { data, loading } = postState;
  return (
    <>
      {data && !loading ? (
        <div>
          <h4>{data.title}</h4>
          <p>{data.body}</p>
        </div>
      ) : (
        <div>Loading post...</div>
      )}
    </>
  );
}

export default App;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.