React Native, unable to scroll flatList - javascript

I created a flatList but it's not scrolling, I'm just rendering it inside View, below is code. I tried to remove View and just render it inside if else but still not scrolling Can some please tell me why it's not scrolling
else {
return (
<View>
{!this.state.isClicked ? (
<FlatList
style={{marginTop: moderateScaleVertical(10)}}
numColumns={1}
data={this.state.industry}
keyExtractor={(industry) => industry.id.toString()}
renderItem={({item}) => (
<SurveyCard
topText={item.topText}
time={item.time}
title={item.title}
date={item.date}
price={item.price}
off={item.off}
image={item.image}
progress={item.progress}
onPress={() => this.props.navigation.navigate(item.onPress)}
/>
)}
/>
) : (
<FlatList
style={styles.industry}
data={this.state.industry}
key={this.state.horizontal ? 'h' : 'v'}
numColumns={2}
keyExtractor={(industry) => industry.id.toString()}
renderItem={({item}) => (
<SurveyCardRow
topText={item.topText}
time={item.time}
title={item.title}
date={item.date}
price={item.price}
off={item.off}
image={item.image}
onPress={() => this.props.navigation.navigate(item.onPress)}
/>
)}
/>
)}
</View>
);
}

Related

How do I change the state present in a specific item within a flatlist?

I am generating a flatlist that contains comments. Inside the comment component, I'm using a state isCollpsed to determine if the individual comment is collapsed or not. Pressing on each individual comment does make it collapse. However, I want to manipulate this state from the parent component without affecting every other comment. How could I achieve this?
I tried using the reference hook to access each individual item in the flatlist but it keeps returning 'undefined'. I'm using the react-native-collapsible library to collapse the comments.
My Flatlist:
<FlatList
data={SAMPLE_COMMENTS}
keyExtractor={keyExtractor}
renderItem={({item})=>
<Comment
ref={(el) => {rowRefs.current[item.id] = el} }
onPress={()=>{rowRefs.current[item.id].collapseFunction()}}
body={item.body}
author={item.author}
level={item.level}
createdAt={item.createdAt}
commentId={item.id}
commentChildren={item.replies} />}
/>
Comment Component :
const [isCollapsed, setIsCollapsed] = useState(false);
const collapseFunction = () => {setIsCollapsed(!isCollapsed)};
return (
<Collapsible collapsed={isCollapsed}>
<TouchableWithoutFeedback onPress={onPress}>
<View style={styles.container}>
</View>
</TouchableWithoutFeedback>
</Collapsible>
you can use recursive function
// add this to parent
<MapComments
comments={SAMPLE_COMMENTS}
childClickHandler={onItemClickHandler}
/>
// MapComments component
const MapComments= ({
Comments= [],
childClickHandler,
}) => {
return (
<ScrollView>
<Tree
CommentTree={CommentTree}
childClickHandler={childClickHandler}
/>
</ScrollView>
);
};
const Tree = ({CommentTree= [], childClickHandler}) => {
return (
<View>
{CommentTree.map(tree => (
<TreeNode
key={tree.commentId}
node={tree}
childClickHandler={childClickHandler}
/>
))}
</View>
);
};
const TreeNode = ({node, childClickHandler}) => {
const [childVisible, setChildVisiblity] = useState(false);
const hasChild = node.commentChildren.length > 0 ? true : false;
return (
<View
style={{marginRight: node.Level > 1 ? 40 : null}}>
<TouchableOpacity
onPress={() =>
hasChild ? setChildVisiblity(prev => !prev) : childClickHandler(node)
}>
<Text numberOfLines={1} style={styles.label}>
{node.body}
</Text>
{hasChild ? (
<AntDesign name={childVisible ? 'minus' : 'plus'}
/>
) : (
<FontAwesome name="circle" />
)}
</TouchableOpacity>
{hasChild && childVisible && (
<Tree
childClickHandler={childClickHandler}
knowledgeTree={node.commentChildren}
/>
)}
</View>
);
};

flatlist and scrollView is not working properly

I'm new in react-native. On one of my screen I'm using flatlist on 4 places but the last flatlist which is displaying at the bottom of screen is not scrolling so I add the scrollView then its working fine but displaying me that error
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation because it can break windowing and other functionality - use another VirtualizedList-backed container instead.
code
const Header = () => {
return (
<View>
<SafeAreaView>
<View style={styles.sellersheaderWrapper}>
<View style={styles.sellersheaderTitle}>
<Text style={styles.sellersheaderTitleText}>
Featured Sellers
</Text>
</View>
<View>
{
isFeatureSeller == '' ?
<View style={[styles.noSpecialOfferCard, {paddingVertical:hp('2%')}]} >
<Text style={[styles.noSpecialOfferCardText, {fontSize:hp('2%')}]}>Currently, No Feature Sellers</Text>
</View>
:
<View>
<FlatList
data={isFeatureSeller}
renderItem={renderCategoryItem}
keyExtractor={item => item.id}
horizontal={true}
showsHorizontalScrollIndicator={false}
/>
</View>
}
</View>
</View>
</SafeAreaView>
<View style={styles.searchWrapper}>
<View style={styles.dobregisterFormWrapperText}>
<TextInput
style={styles.dobregisterInputStyleText}
value={search}
onChangeText={(text) => searchFilterFunction(text)}
onClear={(text) => searchFilterFunction('')}
placeholder="Search ..."
/>
<View>
<SearchIconSvg />
</View>
</View>
</View>
</View>
);
};
const Footer = () => {
return (
<View>
<View style={styles.specialOfferCardWrapper}>
<View style={styles.specialOfferCardTextWrapper}>
<Text style={styles.specialOfferCardText}>Special Offer Cards</Text>
</View>
{isSpecialCards == '' ? (
<View style={styles.noSpecialOfferCard}>
<Text style={styles.noSpecialOfferCardText}>
No Special Offer cards
</Text>
</View>
) : (
<FlatList
data={isSpecialCards}
renderItem={renderCards}
keyExtractor={(item, index) => index.toString()}
horizontal={true}
showsHorizontalScrollIndicator={false}
style={styles.specialCards}
/>
)}
<View
style={[
styles.specialOfferCardTextWrapper,
{paddingBottom: isFeatureSeller == '' ? hp('17%') :hp('10%') },
]}>
<Text style={styles.specialOfferCardText}>Cards</Text>
<FlatList
data={isCard}
renderItem={renderNormalCards}
keyExtractor={item => item.id}
showsVerticalScrollIndicator={false}
scrollEnable={true}
/>
</View>
</View>
</View>
);
};
const MainData = () => {
return(
<View>
{search == '' ? (
<ScrollView>
<View >
<Header />
<Footer />
</View>
</ScrollView>
) : (
<View >
<FlatList
data={filteredDataSource}
renderItem={renderCategoryItemSearch}
keyExtractor={(item, index) => index.toString()}
ListHeaderComponent={Header}
/>
</View>
)}
</View>
)
}
return (
<View style={styles.container}>
{
loading == true ?
<View style={{marginVertical:hp('45%')}} >
<ActivityIndicator size="large" color={colors.primary} />
</View>
:
<MainData/>
}
<View style={styles.bottomNavWrapper}>
<TouchableOpacity
style={styles.storeWrapper}
onPress={() => navigation.navigate('BuyerDashboard')}>
<View style={styles.storeIcon}>
<DashboardReverseSvg />
</View>
</TouchableOpacity>
<View style={styles.dashboardWrapper}>
<View style={styles.dashboardIcon}>
<BuyerStoreReverseSvg />
</View>
<View style={styles.dashboardText}>
<Text style={styles.dashboardTextfont}>Storefront</Text>
</View>
</View>
</View>
</View>
);
};
export default Store;
I want to scroll at here.
<ScrollView>
<View >
<Header />
<Footer />
</View>
</ScrollView>
You can use nestedScrollEnabled prop on your FlatList component
https://reactnative.dev/docs/scrollview#nestedscrollenabled

Flatlist navigation to another screen

So, i've one Flatlist that renders a list of movies, and I'm trying to when I click on it, moves me to a detail page, but it's not working.
Literally, nothing happens and doesn't get any errors on console
My FlatList:
<FlatList
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
horizontal
data={movies}
onPress={() => navigation.navigate('Details')}
renderItem={renderItem}
keyExtractor={(item) => item.id.toString()}
/>
My "renderitem" from flatlist:
const renderItem = ({ item }) => (
<RenderList url={item.poster_path} title={item.original_title} />
);
and that is the RenderList component who fits into the const "renderItem":
<View style={styles.view}>
<Image
style={{ width: 150, height: 220 }}
source={{ uri: 'https://image.tmdb.org/t/p/w500/' + props.url }}
/>
</View>
You should call onPress from a TouchableOpacity that loops for each item.
<FlatList
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
horizontal
data={movies}
onPress={() => navigation.navigate('Details')}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => {
return (
<TouchableOpacity onPress={() => navigation.navigate('Details')}>
<RenderList url={item.poster_path} title={item.original_title} />
</TouchableOpacity>
);
}}
/>
You should have the onPress on each of the list item, not on the Flatlist
<FlatList
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
horizontal
data={movies}
renderItem={renderItem}
keyExtractor={(item) => item.id.toString()}
/>
const renderItem = ({ item }) => {
return (
<TouchableOpacity onPress={() => navigation.navigate('Details')}>
<RenderList url={item.poster_path} title={item.original_title} />
</TouchableOpacity>
);
}

Render a function with onError

I have this object that I want to render when an error occurs while running a grapqhl query (on Apollo's onError):
export const ErrorContainer: React.FunctionComponent = () => {
console.log('container running')
return (
<View style={styles.errorView}>
<Text style={styles.errorText}>Unable to Load Friends</Text>
</View>
);
};
Now on my main screen, I tried this:
const { data, error } = useGetMyProfileQuery({
onCompleted: () => {
//setUserData(data)
},
onError: ErrorContainer
},
});
I also tried this:
{error && <ErrorContainer />}
return (
<SafeAreaView style={styles.safeView}>
<Container style={styles.container}>
<Text
style={styles.backText}
onPress={() => navigation.navigate('Home')}>
Zurück
</Text>
<View style={styles.listHolder}>
{data &&
<FlatList
data={data.me.friends}
horizontal={false}
renderItem={({ item }) => (
<Friend
friend={item}
//onDeleteFriend={onDeleteFriend}
originatorId={data.me.id}
/>
)}
keyExtractor={(item) => item.id.toString()}
ListEmptyComponent={NoFriendsContainer}
/>
}
{error && ErrorContainer}
</View>
</Container>
</SafeAreaView>
);
but although I see the console logs, i dont see the actual content of the ErrorContainer. How else should I call the component?
Passing component as a callback to the hook as here onError: ErrorContainer makes no sense. Despite, component is a function, passing it as a callback will not magically render it.
You have to render it in the template. Like you did above {error && <ErrorContainer />}
Just try to add additional state to your screen
const [isErrorVisible, setErrorVisible] = useState(false);
And then set it in the callback where you passed component before
const { data, error } = useGetMyProfileQuery({
onCompleted: () => {
//setUserData(data)
},
onError: () => {
setErrorVisible(true); // callback now instead of ErrorContainer
}
});
And then use it in your template
return (
<SafeAreaView style={styles.safeView}>
<Container style={styles.container}>
<Text
style={styles.backText}
onPress={() => navigation.navigate('Home')}>
Zurück
</Text>
<View style={styles.listHolder}>
{data &&
<FlatList
data={data.me.friends}
horizontal={false}
renderItem={({ item }) => (
<Friend
friend={item}
//onDeleteFriend={onDeleteFriend}
originatorId={data.me.id}
/>
)}
keyExtractor={(item) => item.id.toString()}
ListEmptyComponent={NoFriendsContainer}
/>
}
{/* here using the flag and rendering the component in template */}
{isErrorVisible && <ErrorContainer />}
</View>
</Container>
</SafeAreaView>
);

Can I enclose a flatlist inside a webview somehow?

In my mainscreen App I am rendering a flatlist of articles , I need to change the code so that the urls open inside the App(like webview) . Does anyone know how can I modify the following code ?
render() {
if (this.state.refreshing) {
return (
<View style={styles.refreshing}>
<ActivityIndicator />
</View>
)
} else {
return (
<List>
<FlatList
data={this.state.articles}
renderItem={({ item }) => <Article article={item} />}
keyExtractor={item => item.url}
refreshing={this.state.refreshing}
onRefresh={this.handleRefresh.bind(this)}
/>
</List>
);
}
}

Categories