Fix list rendering keys and nested list patterns

This commit is contained in:
Adolfo Reyna
2026-02-20 20:13:10 -05:00
parent 487edb4a62
commit d2491800f2
6 changed files with 45 additions and 52 deletions

View File

@@ -1,11 +1,12 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { Searchbar, Title } from 'react-native-paper'; import { Searchbar, Title } from 'react-native-paper';
import { ScrollView, ActivityIndicator, StyleSheet, SafeAreaView, FlatList, View } from 'react-native'; import { ScrollView, ActivityIndicator, StyleSheet, SafeAreaView, View } from 'react-native';
import API from "../API"; import API from "../API";
import CourseCard from "../components/CourseCard"; import CourseCard from "../components/CourseCard";
import { useSnapshot } from 'valtio'; import { useSnapshot } from 'valtio';
import GlobalState from '../contexts/GlobalState.js'; import GlobalState from '../contexts/GlobalState.js';
import i18n from "../i18nMessages.js"; import i18n from "../i18nMessages.js";
import AsyncStorage from '@react-native-async-storage/async-storage';
const getCourses = async (profileObj) => { const getCourses = async (profileObj) => {
let courses; let courses;
@@ -116,15 +117,23 @@ const Courses = () => {
}, 300); }, 300);
setQueryTimer(timerId); setQueryTimer(timerId);
}; };
const renderProfile = (({ item }) => { const renderCourseCards = (items = [], twoCols = false) => {
return (<CourseCard profileObj={item} />); return items.map((item, index) => (
}); <CourseCard
const watchingCourse = (({ item }) => { key={item?._id || item?.profile?._id || `course-${index}`}
return (<CourseCard profileObj={item.profile} />); profileObj={item}
}); twoCols={twoCols}
const renderCoursesQuery = (({ item }) => { />
return (<CourseCard profileObj={item} twoCols={true}/>); ));
}); };
const renderWatchingCards = (items = []) => {
return items.map((item, index) => (
<CourseCard
key={item?.profile?._id || item?._id || `watching-${index}`}
profileObj={item?.profile}
/>
));
};
return ( return (
<SafeAreaView style={styles.container}> <SafeAreaView style={styles.container}>
<Searchbar <Searchbar
@@ -138,53 +147,34 @@ const Courses = () => {
(searchQuery.length === 0 && watching.length) ? (searchQuery.length === 0 && watching.length) ?
<View> <View>
<Title style={styles.title} >{i18n.t("message.continueWatching")}:</Title> <Title style={styles.title} >{i18n.t("message.continueWatching")}:</Title>
<FlatList <ScrollView horizontal={true} showsHorizontalScrollIndicator={false}>
horizontal={true} {renderWatchingCards(watching)}
data={watching} </ScrollView>
renderItem={watchingCourse}
keyExtractor={(item, index) => item?.profile?._id || item?._id || `watching-${index}`}
initialNumToRender={2}
/>
</View> : <></> </View> : <></>
} }
{ {
(searchQuery.length === 0 && groups.length) ? (searchQuery.length === 0 && groups.length) ?
<> <>
<Title style={styles.title} >{i18n.t("message.recentlyAdded")}:</Title> <Title style={styles.title} >{i18n.t("message.recentlyAdded")}:</Title>
<FlatList <ScrollView horizontal={true} showsHorizontalScrollIndicator={false}>
horizontal={true} {renderCourseCards(groups)}
data={groups} </ScrollView>
renderItem={renderProfile}
keyExtractor={item => item._id}
initialNumToRender={2}
/>
</> : <></> </> : <></>
} }
{ {
(searchQuery.length === 0 && popular.length) ? (searchQuery.length === 0 && popular.length) ?
<> <>
<Title style={styles.title} >{i18n.t("message.popularCourses")}:</Title> <Title style={styles.title} >{i18n.t("message.popularCourses")}:</Title>
<FlatList <ScrollView horizontal={true} showsHorizontalScrollIndicator={false}>
horizontal={true} {renderCourseCards(popular)}
data={popular} </ScrollView>
renderItem={renderProfile}
keyExtractor={item => item._id}
initialNumToRender={2}
/>
</> : <></> </> : <></>
} }
{ {
(searchQuery.length !== 0 && groups.length) ? (searchQuery.length !== 0 && groups.length) ?
<> <View style={styles.searchGrid}>
<FlatList {renderCourseCards(groups, true)}
//horizontal={true} </View> : <></>
data={groups}
numColumns={2}
renderItem={renderCoursesQuery}
keyExtractor={item => item._id}
initialNumToRender={8}
/>
</> : <></>
} }
</ScrollView> </ScrollView>
</SafeAreaView> </SafeAreaView>
@@ -203,5 +193,11 @@ const styles = StyleSheet.create({
marginTop: 15, marginTop: 15,
fontWeight: "bold", fontWeight: "bold",
color: "#777" color: "#777"
},
searchGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
paddingHorizontal: 4,
} }
}); });

View File

@@ -157,7 +157,7 @@ let Feed = ({ navigation, route }) => {
<FlatList <FlatList
data={Posts} data={Posts}
renderItem={renderPost} renderItem={renderPost}
keyExtractor={item => item.lastUpdated || item._id || item.ceatedAt} //This may refresh the component keyExtractor={item => item.lastUpdated || item._id || item.createdAt} //This may refresh the component
//ListHeaderComponent={<NewPost newPostCB={(newPost) => setPosts([newPost, ...Posts])} />} //ListHeaderComponent={<NewPost newPostCB={(newPost) => setPosts([newPost, ...Posts])} />}
refreshing={Posts.length === 0} refreshing={Posts.length === 0}
onRefresh={() => { onRefresh={() => {

View File

@@ -180,7 +180,7 @@ let Profile = ({ navigation, route }) => {
<FlatList <FlatList
data={Posts} data={Posts}
renderItem={renderPost} renderItem={renderPost}
keyExtractor={item => item.lastUpdated || item._id || item.ceatedAt} keyExtractor={item => item.lastUpdated || item._id || item.createdAt}
ListHeaderComponent={header} ListHeaderComponent={header}
refreshing={loading} refreshing={loading}
initialNumToRender={3} initialNumToRender={3}

View File

@@ -47,7 +47,7 @@ let Tags = ({ navigation, route }) => {
<FlatList <FlatList
data={Posts} data={Posts}
renderItem={renderPost} renderItem={renderPost}
keyExtractor={item => item.lastUpdated || item._id || item.ceatedAt} keyExtractor={item => item.lastUpdated || item._id || item.createdAt}
ListHeaderComponent={header} ListHeaderComponent={header}
refreshing={loading} refreshing={loading}
initialNumToRender={3} initialNumToRender={3}

View File

@@ -49,7 +49,7 @@ let Post = (props) => {
<FlatList data={userIds} <FlatList data={userIds}
horizontal={true} horizontal={true}
renderItem={renderPost} renderItem={renderPost}
//keyExtractor={item => item} keyExtractor={(item, index) => `${item}-${index}`}
/> />
</View> </View>
</Card.Content> </Card.Content>

View File

@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { FlatList } from 'react-native'; import { View } from 'react-native';
import API from './../API.js'; import API from './../API.js';
import Post from './Post.js'; import Post from './Post.js';
@@ -19,12 +19,9 @@ let SinglePostComponent = ({ postId, hideComments }) => {
} }
}, [postId]); }, [postId]);
return (post._id ? ( return (post._id ? (
<FlatList <View>
data={[post]} <Post post={post} showComments={hideComments ? false : true} />
renderItem={({ item }) => <Post post={item} showComments={hideComments ? false : true}/>} </View>
keyExtractor={item => item._id}
/>
) : null); ) : null);
}; };