由于 URL 构造不正确(404 Not Found),React 组件未显示获取的数据

问题描述 投票:0回答:1

我正在开发一个 React 组件,以使用 Axios 从 Django REST Framework API 获取数据。但是,该组件没有显示获取的数据,并且我在网络选项卡中遇到 404 Not Found 错误。

Post.jsx

import React, { useState, useEffect } from 'react';
import axios from 'axios';

function Post({ postId }) {
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
console.log(postId)
  useEffect(() => {
    const fetchPost = async () => {
      setIsLoading(true);
      const url = `http://127.0.0.1:8000/myapi/posts/${postId}`;
      console.log('Constructed URL:', url);
      try {
        const response = await axios.get(`http://127.0.0.1:8000/myapi/posts/${postId}`); 
        setData(response.data);
      } catch (error) {
        setError(error);
        console.error('Axios request error:', error);
      } finally {
        setIsLoading(false);
      }
    };

    fetchPost();
  }, [postId]);


  return (
    <div>
      {isLoading ? (
        <p>Loading post...</p>
      ) : error ? (
        <p>Error fetching post: {error.message}</p>
      ) : (
        <article>
          <h2>{data.title}</h2>
          <p>{data.content}</p>
          <p>Author: {data.author.username}</p> // Assuming author data is included
          <p>Categories: {data.categories.map((category) => category.name).join(', ')}</p> // Assuming categories data
          <p>Tags: {data.tags.map((tag) => tag.name).join(', ')}</p> // Assuming tags data
          {/* Additional elements for comments, etc. */}
        </article>
      )}
    </div>
  );
}

export default Post;

API响应(直接访问时):

HTTP 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 1,
    "categories": [
        {
            "id": 1,
            "name": "test"
        }
    ],
    "tags": [
        {
            "id": 1,
            "name": "test"
        }
    ],
    "title": "Post1",
    "content": "asdijfoiajfoajsfopajsfpoasjfopajdfpoaodjfpadfiapoidfjapdfoajsdfpoaispdfajsdfopasfiojapdfjaopssdfjpajdfoiajpsfaf",
    "created_at": "2024-01-04T15:57:20.472070Z",
    "author": 1
}

应用程序.js

import React from 'react';
import Header from './components/Header/Header';
import Footer from './components/Footer/Footer';
import Posts from './components/Posts/Posts';
import Post from './components/Post/Post';
import {BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import './Global.css';

function App() {
  return (
    <Router>
      <Header />
      <main>
        <Routes>
          <Route path="/" element={<Posts />} />
          <Route path="/posts/:postId" element={<Post />} />
        </Routes>
      </main>
      <Footer />
    </Router>
  );
}

export default App;

故障排除步骤:

已验证的API响应:API端点在直接访问时返回预期的数据结构。 检查网络请求: 网络选项卡中的请求 URL 为 http://127.0.0.1:8000/myapi/posts/undefined。 这会导致 404 Not Found 错误。 检查的状态值:由于请求失败,未填充数据状态。

附加信息:

React 版本:[电子邮件受保护] axios版本: "axios": "^1.6.4", Django REST框架版本:djangorestframework==3.14.0 浏览器和版本:Chrome版本120.0.6099.129 什么可能导致错误的 URL 构造,以及如何确保将正确的 postId 传递给组件?

任何指导或见解将不胜感激!

javascript reactjs django-rest-framework axios
1个回答
0
投票

问题是您的 Post 组件中的代码使用的是 prop

postId
而不是路由参数
postId
。当您在路由器组件的
element
属性中创建 Post 组件时,您不会将
postId
设置为属性。这就是为什么它总是
undefined
并且您的代码无法按预期工作。此时,您混淆了 React props 的概念以及如何使用
react-router-dom
访问路由参数。

如果你想在函数式 React 组件中访问像

:postId
这样的路由参数,你可以使用
useParams
react-router-dom
钩子。 该挂钩使您可以访问所有路由参数。

解决方案:

应用程序

...
function App() {
  return (
    <Router>
      <Header />
      <main>
        <Routes>
          <Route path="/" element={<Posts />} />
          // you define a route parameter :postId, which can get accessed in your Post component via useParams hook
          <Route path="/posts/:postId" element={<Post />} />
        </Routes>
      </main>
      <Footer />
    </Router>
  );
}

发帖

...
import { useParams } from 'react-router-dom';
// removed prop postId
function Post() {
  // get the postId route param
  const { postId } = useParams()
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
console.log(postId)
  useEffect(() => {
    const fetchPost = async () => {
      setIsLoading(true);
      const url = `http://127.0.0.1:8000/myapi/posts/${postId}`;
      console.log('Constructed URL:', url);
      try {
        const response = await axios.get(`http://127.0.0.1:8000/myapi/posts/${postId}`); // Corrected URL
        setData(response.data);
      } catch (error) {
        setError(error);
        console.error('Axios request error:', error);
      } finally {
        setIsLoading(false);
      }
    };

    fetchPost();
  }, [postId]);


  return (...);
}

export default Post;
© www.soinside.com 2019 - 2024. All rights reserved.