React componentDidMount 和 setState 似乎不会导致重新渲染以显示我的组件
React componentDidMount and setState not seeming to cause a rerender to show my component
/*获取数据并设置状态后,我正在尝试生成一个 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})
}
});
其次,请记住您在 class 中,因此当您使用关键字 this
时,this.readyState
和 this.responseText
引用 class,不是您期望的 XHR 对象。为了完成这项工作,您应该将 readystatechange
的回调函数更改为 lambda 函数,然后将 this
替换为 xhr
,但您应该保留 this
实际上在 this.setState
:
中引用了你的 class
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
问题的更多信息,请查看 this question。
/*获取数据并设置状态后,我正在尝试生成一个 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})
}
});
其次,请记住您在 class 中,因此当您使用关键字 this
时,this.readyState
和 this.responseText
引用 class,不是您期望的 XHR 对象。为了完成这项工作,您应该将 readystatechange
的回调函数更改为 lambda 函数,然后将 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
问题的更多信息,请查看 this question。