reactjs - 反应原生的FlatList不从状态呈现数据
问题描述
FlatList 不是从状态呈现数据,但它适用于 DATA 变量。this.state.DATA
是一个对象数组,就像 DATA 变量一样。DATA 变量只是 reactnative 文档中给出的虚拟变量。我想显示this.state.DATA
.
import React, { Component } from 'react';
import { Text, View ,FlatList} from 'react-native';
import SectionHeader from '../SectionHeader';
import {TableHeader,TableHeaderText,IssueContainer} from './style';
import {CheckOutlined,InfoCircleOutlined,CaretDownOutlined} from '@ant-design/icons'
const DATA = [
{
id: '1',
title: "No show password eye button in Login form",
},
{
id: '2',
title: 'Second Item',
},
{
id: '3',
title: 'Third Item',
},
];
var repos=[],issues=[];
export default class App extends Component {
state={isLoading:true};
componentDidMount() {
fetch('https://api.github.com/orgs/anitab-org/repos')
.then((response)=>response.json())
.then((json)=> json.forEach(function(repo,idx){
repos.push(repo.name);
fetch('https://api.github.com/repos/anitab-org/'+repo.name+'/issues')
.then((response)=>response.json())
.then((json)=>json.forEach(function(issue,idx){
var flag=false;
var issue_tmp={
id:issue.id.toString(),
url:issue.html_url,
title:issue.title,
milestones:issue.milestones,
comments:issue.comments,
number:issue.number,
assignees:issue.assignees,
labels:[],
};
issue.labels.forEach(function(label){
if(label.name==="First Timers Only")
flag=true;
issue_tmp.labels.push({
id:label.id,
name:label.name,
color:label.color
})
})
if(flag===true && issue_tmp!=null)
issues.push(issue_tmp)
}));
}))
.then(()=>{
this.setState({
repos:repos,
DATA:issues,
isLoading:false,
});
})
}
render() {
if(this.state.isLoading===true)
return(<></>)
else{
return (
<View style={{alignItems: 'left',width:'80%'}}>
<SectionHeader title="SOME COOL FIRST-TIME ISSUES TO WORK ON"/>
<TableHeader>
<TableHeaderText style={{color:'#000',textAlign:'left'}}><InfoCircleOutlined /> 5 Open</TableHeaderText>
<Text style={{flex:6,color:'#586069'}}><CheckOutlined /> 45 Closed</Text>
<TableHeaderText>Author <CaretDownOutlined /></TableHeaderText>
<TableHeaderText>Label <CaretDownOutlined /></TableHeaderText>
<TableHeaderText>Milestone <CaretDownOutlined /></TableHeaderText>
<TableHeaderText>Assignee <CaretDownOutlined /></TableHeaderText>
<TableHeaderText>Sort <CaretDownOutlined /></TableHeaderText>
</TableHeader>
<FlatList
data={this.state.DATA}
renderItem={({item})=>(
<IssueContainer key={item.id}><Text>{item.title}</Text></IssueContainer>
)}
keyExtractor={item => item.id}
/>
</View>
);
}
}
};
解决方案
它不起作用的原因是因为你有嵌套的承诺。外部then
不会等待内部执行以下代码。这种方式 last then
withsetState
在没有解决这些承诺的情况下执行:
.then((json)=> json.forEach(function(repo,idx){
// bunch of promises being executed here with some chained then blocks
// outer 'then' chain doesn't wait these promises to resolve
}))
.then(()=>{
// since the previous one doesn't wait its inner promises to execute
// this chained 'then' is executed without those promises return their values
this.setState({
repos:repos,
DATA:issues,
isLoading:false,
});
我重写了您的代码,async/await
因为有很多承诺,这很难阅读。我使用Promise.all来包装所有提取。我还将您的问题处理抽象为它自己的规范化功能:
state = {
isLoading: true,
repos: [],
DATA: [],
};
async componentDidMount() {
const repos = [];
try {
const response = await fetch('https://api.github.com/orgs/anitab-org/repos');
const jsonData = await response.json();
const DATA = await Promise.all(jsonData.map(async ({ name }) => {
repos.push(name);
const issuesResponse = await fetch(`https://api.github.com/repos/anitab-org/${name}/issues`);
const issuesJSON = await issuesResponse.json();
const repoIssues = issuesJSON.map(this.normalizeIssue);
return repoIssues.filter(issue => issue !== undefined);
}))
// DATA needs to be flat since it's an array of arrays
this.setState({
repos,
DATA: DATA.flat(),
isLoading:false,
})
} catch (error) {
console.log(error);
}
}
normalizeIssue = (issue) => {
let flag = false;
const issueNormalized = {
id:issue.id.toString(),
url:issue.html_url,
title:issue.title,
milestones:issue.milestones,
comments:issue.comments,
number:issue.number,
assignees:issue.assignees,
labels:[],
};
issue.labels.forEach(function(label){
if(label.name === "First Timers Only") flag = true;
issueNormalized.labels.push({
id:label.id,
name:label.name,
color:label.color
})
})
if(flag === true && issueNormalized !== null) return issueNormalized
}
推荐阅读
- python - 如何为 Pandas 中的不同段构建运行 PCA 和 K-means 的循环
- oracle - Oracle 是否支持 SQL 语句中的 RETURNING?
- java - 是否可以使用属性文件名动态配置 log4j2.xml?
- python - Tweepy stream.filter 使用现金标签
- php - 在 FB 和 FB OG 上共享时发送信息,通过使用 $_GET 的 URL 不起作用
- angular - 角度 onclick 选择多个字段获取值并更改背景颜色
- c# - 统一、透明背景和多显示器
- ios - 从最小化状态iOS返回后调用计时器
- javascript - 处理 dropzone 表单中的复选框
- api - Binance API Orderbook 深度检索问题