繁体   English   中英

反应原生的 FlatList 不呈现来自 state 的数据

[英]FlatList in react native not rendering data from state

FlatList 不呈现来自 state 的数据,但它适用于 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外部不会等待内部执行以下代码。 这种方式then使用setState执行,而没有解决这些承诺:

.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来包装所有提取。 此外,我将您的问题处理抽象为它自己的规范化 function:

  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
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM