javascript - 更新组件状态以使用 Redux 查看 Flatlist 中的数据

标签 javascript reactjs react-native redux react-native-flatlist

我正在使用 Redux 来获取数据并将其添加到存储中,添加后我尝试在平面列表中查看结果,但记录器中出现以下错误消息

enter image description here

我搜索了一段时间,发现我必须使用条件来阻止平面列表在获取数据并将其添加到存储之前呈现,所以我尝试将我的数据列表分配给我的本地组件状态componentWillReceiveProps 强制组件重新渲染并查看平面列表中的数据列表,但突然出现相同的错误,尽管我已经使用了使平面列表等待数据接收并保存到存储的条件。

数据如下所示

enter image description here

包含平面列表的 homePage.js

import React from 'react';
import { Text, View, ScrollView, TouchableOpacity, FlatList } from 'react- 
native';
import {Container, Header, Content, Item, Input, Button} from 'native-base';
import RPostCard from './reusablePostCard';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import Foundation from 'react-native-vector-icons/Foundation';

class HomePage extends React.Component {
constructor(props){
    super(props);
    this.state = {
        postsData: []
    }
}

componentDidMount(){
    this.props.getNewsFeedPosts();
}

componentWillReceiveProps(nextProps){
    if (nextProps.postsData !== this.props.postData){
        this.setState({postsData: nextProps.postsData})
    }
}

render() {
    let { postsData, postsFetched } = this.props;
    return (
        <View style={styles.container}>
            <Header style={styles.header}>
                <View style={styles.messagesIconView}>
                    <TouchableOpacity onPress={() => this.props.navigation.navigate('Chat')}>
                        <FontAwesome5 name='comment' size={23} color='#ffffff'/>
                    </TouchableOpacity>
                </View>
                <View style={styles.telephoneIconView}>
                    <TouchableOpacity>
                        <Foundation name='telephone' size={25} color='#ffffff'/>
                    </TouchableOpacity>
                </View>
                <Content style={styles.searchContent}>
                    <Item style={styles.searchItem}>
                        <Input placeholder='ابحث هنا' placeholderTextColor='#ffffff' style={styles.inputValueStyle}/>
                        <FontAwesome5 name='search' size={15} color='#ffffff' style={styles.searchIconStyle}/>
                    </Item>
                </Content>
            </Header>
            {(this.state.postsData.length === 0) ?
                null
                :
                <ScrollView>
                    <FlatList
                        data={this.state.postsData}
                        renderItem={({postData}) => (<Text>{postData.title}</Text>)}
                    />
                </ScrollView>
            }
        </View>
    );
}
}

HomePage.defaultProps = {
}

export default HomePage;

包含mapstatetoprops和mapActionCreators的Home容器

import {connect} from "react-redux";
import HomePage from "../../components/HomeScreens/HomePage";
import {
    getNewsFeedPosts
} from "../../modules/Home";

const mapStateToProps = (state) =>({
    postsData: state.Home.posts,
    postsFetched: state.Home.postsFetched,
});

const mapActionCreators = {
    getNewsFeedPosts
};
export default connect(mapStateToProps, mapActionCreators)(HomePage);

HomePage.js 中 componentdidmount() 调用的 Action Handler 函数

function handleNewsFeedPosts(state, action){
const postsData = action.payload.data.posts;
const likesNo = action.payload.data.likes;
const commentsNo = action.payload.data.comments;
const post = {};
var posts = [];
var postsIds = [];
var imageLink = "http://192.168.1.117:3000/image/";
var month_ar = '';
var month_en = '';
var oldPostsState = [];
var oldPostsIdsState =[];
for (i = 0; i < postsData.length; i++) {
    //filter description from <p> </p> tags
    const description = postsData[i].description;
    const filteredDescription = description.replace(/<[^>]*>/g, '');

    //filter date and time from  '-' and split date and time converting it to arabic
    const created_at = postsData[i].created_at.replace(/-/g, ' ');
    created_at = postsData[i].created_at.replace(/:/g, ' ');
    const created_at_filter = postsData[i].created_at.split(' ');
    const date = created_at_filter[0].split('-');
    const month = parseInt(date[1]);

    switch (month) {
        case 1:
            month_en = " January ";
            month_ar = " يناير ";
            break;
        case 2:
            month_en = " February ";
            month_ar = " فبراير ";
            break;
        case 3:
            month_en = " March ";
            month_ar = " مارس ";
            break;
        case 4:
            month_en = " April ";
            month_ar = " ابريل ";
            break;
        case 5:
            month_en = " May ";
            month_ar = " مايو ";
            break;
        case 6:
            month_en = " June ";
            month_ar = " يونيو ";
            break;
        case 7:
            month_en = " July ";
            month_ar = " يوليو ";
            break;
        case 8:
            month_en = " August ";
            month_ar = " أغسطس ";
            break;
        case 9:
            month_en = "September";
            month_ar = "سبتمبر";
            break;
        case 10:
            month_en = " October ";
            month_ar = " أكتوبر ";
            break;
        case 11:
            month_en = " November ";
            month_ar = " نوفمبر ";
            break;
        case 12:
            month_en = " December ";
            month_ar = " ديسمبر ";
            break;
    }

    const created_at_ar = created_at.replace(/\d/g, d =>  '٠١٢٣٤٥٦٧٨٩'[d]);

    //Ready English format
    const created_at_en = setCharAt(created_at, 4, month_en);

    //Ready Arabic format
    created_at_ar = setCharAt(created_at_ar, 4, month_ar);

    //Link post image name with the complete require link
    const image = postsData[i].image;
    imageLink = imageLink.substr(0,imageLink.length) + image;


    const post = {
        id: postsData[i].id,
        title: postsData[i].title,
        description: filteredDescription,
        type: postsData[i].type,
        category_id: postsData[i].category_id,
        image: imageLink,
        created_at_ar: created_at_ar,
        created_at_en: created_at_en,
        likesNo: likesNo[i],
        commentsNo: commentsNo[i],
    }

    //push posts data to one array 
    posts.push(post);

    //collect posts id to send it back and get a new array of posts
    postsIds.push(post.id);

    }
    if (fetchDataCounter == 0){
        var newPostsState = posts;
        var newPostsIdsState = postsIds;
    }
    else{
        //merge old posts state array with new one
        oldPostsState = action.posts;
        var newPostsState = oldPostsState.concat(posts);

        //merge old posts ids state array with new one
        oldPostsIdsState = action.postsIds;
        var newPostsIdsState = oldPostsIdsState.concat(postsIds);
    }

    fetchDataCounter ++;
    return update(state, {
        posts:{
            $set: newPostsState
        },
        postsIds:{
            $set: newPostsIdsState
        },
        postsFetched: {
            $set: true
        }
    });
}



const ACTION_HANDLER = {
    NEWS_FEED_POSTS:handleNewsFeedPosts
}
const initialState = {
    posts:[],
    postsFetched: false,
    postsIds:{},
    data: 'blablabla...'
}

最佳答案

首先,FlatList 会自行滚动,不需要将其包装在 ScrollView 中。

另外,我认为问题就在这里

renderItem={({postData}) => (<Text>{postData.title}</Text>)}

renderItem 是一个函数,其对象参数具有以下结构:

export interface ListRenderItemInfo<ItemT> {

   item: ItemT;

   index: number;

   separators: {
       highlight: () => void;
       unhighlight: () => void;
       updateProps: (select: "leading" | "trailing", newProps: any) => void;
   };
}

您需要像这样在 renderItem 函数中提取项目对象

renderItem={({item}) => (<Text>{item.title}</Text>)}

然后就可以了:)

关于javascript - 更新组件状态以使用 Redux 查看 Flatlist 中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53206885/

相关文章:

javascript - 如何覆盖 div 中除一个元素之外的所有内容

javascript - 在 AJAX 调用上返回 html 表单字段

javascript - 执行动画时无效 prop 'paddingLeft'

android - 如何运行/安装 React Native 官方示例?

javascript - 使用 React 和 React Native 的 Yarn 工作区

javascript - 来自 Java 程序的 ChartJS 折线图或条形图

javascript - 使用 Javascript 的 Facebook API

reactjs - 使用某些 React-Bootstrap 组件会导致违反不变性

javascript - 在 React.js 和 React Native 应用程序之间重用代码

javascript - Webpack、React 和 Babel,不渲染 DOM