reactjs - React componentDidMount 和 setState 似乎不会导致重新渲染以显示我的组件
问题描述
/*在获取数据并设置为状态后,我正在尝试生成要显示的 jsx 项目数组。但是数组显示为空并且没有渲染。
尝试过,硬编码,这行得通。尝试登录数据,它确实显示状态正在接收数据。
从下面的代码中删除了我的授权令牌。*/
import React, { Component } from 'react';
import AddCard from '../AddCard/AddCard.js';
import KanCard from '../KanCard/KanCard.js';
import './CardHolder.scss';
export default class CardHolder extends Component {
constructor(props){
super(props);
this.state = {
stories: [],
inProgressTasks: [],
completeTasks: [],
};
}
componentDidMount(){
// let id = this.props.id;
let id = 168881069;
let completetask = [];
let progresstask =[];
var data = null;
var xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
let parsedResponse = JSON.parse(this.responseText);
for( let taskResponse of parsedResponse ){
let task = {
key:taskResponse.id,
id:taskResponse.id,
story_id:taskResponse.story_id,
complete:taskResponse.complete,
description: taskResponse.description,
}
if(!taskResponse.complete){
progresstask.push(task)
} else {
completetask.push(task);
}
}
}
});
this.setState({inProgressTasks:progresstask, completeTasks:completetask})
xhr.open("GET", `https://www.pivotaltracker.com/services/v5/projects/2401708/stories/${id}/tasks`);
xhr.setRequestHeader("X-TrackerToken", "296912a3ff4ddcda26b4a419934b3051");
xhr.setRequestHeader("Accept", "*/*");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.send(data);
}
render(){
let completeTasks = this.state.completeTasks.map((task)=>{
return (
<KanCard
key = {task.id}
id = {task.id}
story_id = {task.story_id}
complete = {task.complete}
description = {task.description}
/>
)
})
let inProgressTasks = this.state.inProgressTasks.map((task)=>{
return (
<KanCard
key = {task.id}
id = {task.id}
story_id = {task.story_id}
complete = {task.complete}
description = {task.description}
/>
)
})
console.log(inProgressTasks)
return (
<div className='holder'>
<h2> {this.props.title} </h2>
<div>
<h3>In Progress</h3>
{inProgressTasks}
</div>
<div>
<h3>Complete</h3>
{completeTasks}
</div>
<AddCard />
</div>
)
}
}
解决方案
您设置呼叫和更新状态的方式存在一些问题。
首先,确保在收到响应时更新您的状态,毕竟这是一个异步请求,您需要等待获取某些内容,然后再更新您的状态。
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
let parsedResponse = JSON.parse(this.responseText);
for( let taskResponse of parsedResponse ){
let task = {
key:taskResponse.id,
id:taskResponse.id,
story_id:taskResponse.story_id,
complete:taskResponse.complete,
description: taskResponse.description,
}
if(!taskResponse.complete){
progresstask.push(task)
} else {
completetask.push(task);
}
}
this.setState({inProgressTasks:progresstask, completeTasks:completetask})
}
});
其次,请记住您在一个类中,因此当您使用关键字时引用该类,this.readyState
而不是您期望的 XHR 对象。为了使这项工作,您应该将的回调函数更改为 lambda 函数,然后替换for ,但您应该将实际引用您的类的 保留在:this.responseText
this
readystatechange
this
xhr
this
this.setState
xhr.addEventListener("readystatechange", () => {
if (xhr.readyState === 4) {
let parsedResponse = JSON.parse(xhr.responseText);
for( let taskResponse of parsedResponse ){
let task = {
key:taskResponse.id,
id:taskResponse.id,
story_id:taskResponse.story_id,
complete:taskResponse.complete,
description: taskResponse.description,
}
if(!taskResponse.complete){
progresstask.push(task)
} else {
completetask.push(task);
}
}
this.setState({inProgressTasks:progresstask, completeTasks:completetask})
}
});
我试图在这里复制您的问题:
我正在使用一个愚蠢的 api 并使用响应数据更新我的状态。玩弄它。readystatechange
在最初设置时将 的回调函数从 lambda 函数更改为匿名函数,然后看看会发生什么。
要阅读有关该this
问题的更多信息,请查看此问题。
推荐阅读
- c# - 如何使用 Linq C# 将字符串转换为十进制以进行求和
- selenium-ide - 是 selenium IDE 测试用例,关键字驱动测试方法的一个例子
- select - 如何在项目中获取 v-select 项目?
- python - 从字典中抓取 Aiohttp json
- java - 从同一数据库的另一个模式访问序列时,序列不存在错误
- date - 将数据与当前日期谷歌脚本进行比较
- javascript - 在 HTML 中运行时创建的新行的放置问题
- java - 运行 ESRestTestCase 时缺少类文件夹的 Jar 地狱
- keras - 训练具有各种噪声标准差的 DNN
- selenium - whatsapp bot中的硒关闭警报