无法在 React 中呈现来自 REST API GET(在 Django 中管理)响应的数据

Posted

技术标签:

【中文标题】无法在 React 中呈现来自 REST API GET(在 Django 中管理)响应的数据【英文标题】:Cannot render data from REST API's GET (managed in Django) response in React 【发布时间】:2022-01-10 11:30:28 【问题描述】:

我遇到了数据没有从 React 中的 API 响应呈现的问题,即使我确实收到了它。

我有以下“管理员通知”组件:

import React from "react";
import './Admin-notifications.css';
import axios from 'axios'; 


class AdminNotifications extends React.Component 
    constructor()
        super();
        this.state = 
            events:[
                
                    "id": 1,
                    "name": "Fotosinteza plantelor",
                    "start_date": 1637496120,
                    "end_date": 4098071460,
                    "location": "Cluj-Napoca",
                    "description": "Aduceti planta",
                    "status": "pending",
                    "id_organizer": 2,
                    "id_type": 1
                ,
                
                    "id": 2,
                    "name": "Cantecul greierilor de peste imas",
                    "start_date": 1637669280,
                    "end_date": 4098071460,
                    "location": "Imas",
                    "description": "In padurea cu alune aveau casa 2 pitici",
                    "status": "pending",
                    "id_organizer": 2,
                    "id_type": 1
                ,
                
                    "id": 4,
                    "name": "test",
                    "start_date": 1637518260,
                    "end_date": 4098071460,
                    "location": "test",
                    "description": "test",
                    "status": "pending",
                    "id_organizer": 2,
                    "id_type": 1
                
            ]
        
        this.state2=
            events:[],
        
    
    getEvents()
        axios
            .get("http://127.0.0.1:8000/api/getevents")
            .then(response =>
                this.state2.events = response.data;
            ) 
            .catch(err => console.log(err));
    ;

    render()
        this.getEvents();
        console.log(this.state);
        console.log(this.state2);
        const events = this.state2;
        return(
            <main className="mw6 center main">
                
                    events.map((event)=>
                      
                        return(
                            <article key=event.id className="dt w-100 hight padd bb  pb2  component" href="#0">
                                <div className="col-md-3">
                                    <div className="dtc w2 w3-ns v-mid">
                                        /* <img src=event.img 
                                        
                                        className="ba b--black-10 db br-100 w2 w3-ns h2 h3-ns"/> */
                                    </div>
                                    <div className="dtc v-mid pl3">
                                        <h1 className="f6 f5-ns fw6 lh-title black mv0">event.name </h1>
                                        <h2 className="f6 fw4 mt0 mb0 black-60">event.description</h2>
                                    </div>
                                    <div className="dtc v-mid">
                                        <form className="w-100 tr">
                                        <button className="btn" type="submit">Accept</button>
                                        </form>
                                    </div>
                                    <div className="dtc v-mid">
                                        <form className="w-100 tr">
                                        <button className="btn" type="submit">Decline</button>
                                        </form>
                                    </div>

                                </div>
                            </article>
                    ))
                
            </main>
        )
    


export default AdminNotifications;

在那里,你可以看到我有两个状态:state 和 state2。 “this.state”是来自 API 的数据的硬编码变体,“this.state2”是来自 API 的数据。

这是来自 render() 的 console.log() 的图片,其中第一个 'events' 属于“state”,第二个属于“state2”:

如果我们使用“状态”进行映射,以下是网站的外观:

const events = this.state;
        return(
            <main className="mw6 center main">
                
                    events.map((event)=>
                    ...

图片:

这很好,这就是我希望网站的样子。

下面是使用 API 数据的样子:

const events = this.state2;
        return(
            <main className="mw6 center main">
                
                    events.map((event)=>
                    ...

图片:

以下是 API 调用:

我也可以给你提供后端代码。

API 视图:

@api_view(['GET'])
def getevents(request):
    if request.method == "GET":
        events = Event.objects.all()
        serializer = EventSerializer(events, many=True)
        return Response(serializer.data)

是的,我确实注意没有覆盖。这是这条路径的唯一视图。

这是我用过的序列化器:

class EventSerializer(serializers.ModelSerializer):
    class Meta:
        model = Event
        fields = '__all__'

这里是“事件”的模型:

class Event(models.Model):
    name = models.TextField()
    id_organizer = models.ForeignKey(User, on_delete=CASCADE, db_column='id_organizer')
    start_date = models.BigIntegerField()
    end_date = models.BigIntegerField()
    location = models.TextField()
    description = models.TextField()
    id_type = models.ForeignKey(EventType, on_delete=CASCADE, db_column='id_type')
    status = models.CharField(max_length = 50)
    class Meta:
        db_table="events"

这是我从中获取数据的表的数据库:

在 Django 中返回数据之前,我进行了打印。结果如下:

@api_view(['GET'])
def getevents(request):
    if request.method == "GET":
        events = Event.objects.all()
        serializer = EventSerializer(events, many=True)
        print(serializer.data)
        return Response(serializer.data)

图片

您可能已经注意到,API 被调用了两次。我无法真正解释为什么会发生这种情况,但为了确认这一点,如果我在调用 API 的函数中添加一个 console.log(),我得到了 console.log() 两次,这意味着该函数确实调用两次。

getEvents()
        
        axios
            .get("http://127.0.0.1:8000/api/getevents")
            .then(response =>
                this.state2.events = response.data;
                console.log("test1");
            ) 
            .catch(err => console.log(err));
    ;

图片:

我不知道为什么它被调用了两次。但我确实怀疑这是问题之一。

这里是 URL 路径:

urlpatterns = [
    path('api/login', views.login),
    path('api/addevent', views.addevent),
    path('api/getevents', views.getevents),
]

我尝试使用 Promise 类型,以不同的方式解析数据并将其推送到“state2”,将数据直接返回到渲染中,但没有任何效果。

【问题讨论】:

this.state 在 React 中实际上修改了状态,而 this.state2 什么都不做。切换两个变量名并查看 API 中的数据 【参考方案1】:

您不能直接操作状态,必须使用 this.setStae 函数来更新它,如下所示

getEvents()
  axios
    .get("http://127.0.0.1:8000/api/getevents")
    .then(response =>
      this.setState(events:response.data)
      console.log("test1");
    )
    .catch(err => console.log(err));
;

【讨论】:

【参考方案2】:

找到解决方案:

constructor()
        super();
        this.state = 
            events:[]
        
    
    componentDidMount()
        axios
        .get("http://127.0.0.1:8000/api/getevents")
        .then(response =>
            this.setState(events: response.data);
        ) 
        .catch(err => console.log(err));
    

说实话,我不知道为什么它不能以另一种方式工作。但很高兴解决了这个问题。

【讨论】:

以上是关于无法在 React 中呈现来自 REST API GET(在 Django 中管理)响应的数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React 中使用 fetch 正确处理来自 REST API 的数据对象

React 组件在来自 JSON 对象的选项卡中呈现动态内容

React Router Link 更改 URL 但不呈现组件 - 休息国家 API

如何在 React js 中将 HTML 模板呈现为来自 json 的响应

从 REST API 填充上下文并在带有 useEffect 和 useContext 的 React 组件中使用它

无法显示来自 Wordpress REST API 自定义端点的自定义字段