Обновление состояния компонента для просмотра данных в Flatlist с Redux - PullRequest
0 голосов
/ 08 ноября 2018

Я использую Redux для извлечения данных и добавления их в хранилище, и после добавления я пытался просмотреть результат в «плоском списке», но в логгере появляется следующее сообщение об ошибке

enter image description here

и я некоторое время искал, и я понял, что мне нужно использовать условия, чтобы запретить рендеринг Flat List до того, как данные будут извлечены и добавлены в хранилище, поэтому я попытался присвоить свой список данных состоянию локального компонента с помощью 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

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);

Функция обработчика действий, вызывающая componentdidmount () в HomePage.js

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...'
}

1 Ответ

0 голосов
/ 08 ноября 2018

Прежде всего, 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;
   };
}

Вам нужно извлечь объект item в вашей функции renderItem, как это

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

Тогда это будет работать:)

...