我正在使用 Redux 来获取数据并将其添加到存储中,添加后我尝试在平面列表中查看结果,但记录器中出现以下错误消息
我搜索了一段时间,发现我必须使用条件来阻止平面列表在获取数据并将其添加到存储之前呈现,所以我尝试将我的数据列表分配给我的本地组件状态componentWillReceiveProps 强制组件重新渲染并查看平面列表中的数据列表,但突然出现相同的错误,尽管我已经使用了使平面列表等待数据接收并保存到存储的条件。
数据如下所示
包含平面列表的 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/