how to create an infinite loop FlatList - reactjs

I have a flatlist rendering a posterlist but i want it to loop infinitely so for example if posterIds are [1,2,3,4] I want it to loop 1,2,3,4,1,2,3,4,1,2,3,4,... etc
import { View, FlatList, Dimensions } from "react-native";
import moviesData from "../Fixtures/movieData.json";
import Poster from "./Poster";
const screenWidth = Dimensions.get("screen").width;
const ITEM_SIZE = screenWidth * 0.8;
const SPACING = screenWidth * 0.015;
const FULLSIZE = ITEM_SIZE + SPACING * 2;
const PosterList = ({ posterStyle, onPressPoster }) => {
return (
<View style={{ width: "100%", height: "100%" }}>
<FlatList
data={moviesData}
snapToAlignment="center"
snapToInterval={FULLSIZE}
bounces={false}
decelerationRate="fast"
renderItem={({ item }) => (
<Poster
imageUrl={item.poster}
style={[
posterStyle,
{ width: ITEM_SIZE, marginHorizontal: SPACING },
]}
onPressPoster={onPressPoster}
/>
)}
horizontal
showsHorizontalScrollIndicator={false}
/>
</View>
);
};
export default PosterList;

Related

ScrollView Getting error undefined is not a function, js engine: hermes

I Tried to using useRef to automate scroll if I press button
The idea is scroll with my scrollview and then I can press button to scroll to another set of view in my scrollview
this is my complete slider code
import { height } from 'deprecated-react-native-prop-types/DeprecatedImagePropType'
import { onChange } from 'deprecated-react-native-prop-types/DeprecatedTextInputPropTypes'
import React , {useState,useRef} from 'react'
import { StyleSheet, View , Text , ScrollView , Pressable , Image, Dimensions , TouchableOpacity} from 'react-native'
const WIDTH = Dimensions.get('window').width
const HEIGHT = Dimensions.get('window').height
const ImageSlider = ({slides}) => {
const refScrollview = useRef()
const [currentIndex,setCurrentIndex] = useState(0)
// console.log(slides[currentIndex].banner)
const [imageActive,setImageActive] = useState(1)
const onChange = (nativeEvent) =>{
if(nativeEvent){
const slide = Math.ceil(nativeEvent.contentOffset.x / nativeEvent.layoutMeasurement.width)
if(slide != imageActive){
console.log(slide)
setImageActive(slide)
console.log(refScrollview.current)
}
}
}
return(
<View style={{flex:1}}>
<ScrollView
ref={refScrollview}
// onContentSizeChange={(contentWidth, contentHeight)=> {refScrollview.current.scrollToEnd({animated: true})}}
onScroll={({nativeEvent}) => onChange(nativeEvent)}
showsHorizontalScrollIndicator={false}
pagingEnabled
horizontal
style={styles.wrap}
>
{
slides.map((e,index)=>
// <Text>{e.banner}</Text>
<View style={{flex:1}} key={index}>
<Image source={e.banner}
style={[styles.wrap]}
>
</Image>
<Image source={e.bannerFace}
style={styles.bannerFace}
>
</Image>
</View>
)
}
</ScrollView>
<View style={styles.wrapDot}>
{
slides.map((e,index)=>
<TouchableOpacity key={index} style={imageActive == index ? styles.lineActive : styles.lineOnly} onPress={() => {
refScrollview.current.scrollTo()}}>
</TouchableOpacity>
)
}
</View>
</View>
)
}
let styles = StyleSheet.create({
backgroundImage: {
flex:1,
width: null,
height: null,
// width: 400,
// height: 400,
// resizeMode: 'cover',
},
bannerFace:{
position:'absolute',
bottom:0,
right:0,
flex: 1,
width: 150,
height: 150,
resizeMode: 'contain'
},
wrap:{
width:WIDTH,
height:'100%'
},
wrapDot:{
position:'absolute',
bottom:20,
left:50,
flexDirection:'row',
alignSelf:'center'
},
lineOnly:{
padding:5,
width:70,
borderRadius:15,
borderColor:'#CECECE',
backgroundColor:'#CECECE',
marginHorizontal:5
},
lineActive:{
padding:5,
width:70,
borderRadius:15,
borderColor:'#FFF',
backgroundColor:'#FFF',
marginHorizontal:5
}
})
export default ImageSlider
I get the error TypeError: undefined is not a function, js engine: hermes
whenever i try to push/use this
onPress={() => {
refScrollview.current.scrollTo()}}
It looks like there is no scrollTo() function , am I doing this wrong ? or is it my react node.modules ?

How to use a Pan responder to scroll a scrollView (React)

I have a pan responder overlaying the whole screen and a scrollview underneath it.
I would like to call the scrollTo() method and using Pan responders X/Y travel positions to scroll.
I am using this Pan Responder example code to create a Y value that can increment or decrement as you swipe up or down on the screen.
https://reactnative.dev/docs/panresponder
I don't know how to get myScroll view to listen to this Y value change.
Any help is appreciated. thanks
// You should be able to run this by copying & pasting
import { createRef, useRef } from "react";
import { Animated, PanResponder, StyleSheet, Text, View } from "react-native";
// some refs...
const scrollRef = createRef();
const buttonRef = createRef();
// panResponder Hook
const useScreenPanResponder = () => {
const pan = useRef(new Animated.ValueXY()).current;
const panResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: () => {
pan.setOffset({
y: pan.y._value,
});
},
onPanResponderMove: Animated.event([null, { dy: pan.y }]),
onPanResponderRelease: () => {
pan.flattenOffset();
},
})
).current;
return { pan, panResponder };
};
// custom button
const ButtonWrapper = ({ children }) => {
return (
<View
onTouchStart={() => {
buttonRef.current = Date.now();
}}
onTouchEnd={() => {
if (Date.now() - buttonRef.current < 500) {
console.log("Actual Press");
} else {
console.log("Not a Press");
}
}}
>
{children}
</View>
);
};
// long list of text
const Content = () => {
const data = Array.from(Array(100));
return (
<View style={{ backgroundColor: "orange", flexDirection: "column" }}>
{data.map((i) => (
<Text style={{ fontSize: 17, color: "black" }}>Some Content</Text>
))}
</View>
);
};
export default function App() {
const { pan, panResponder } = useScreenPanResponder();
console.log("pan!", pan);
console.log("scrollRef", scrollRef);
const scrollToPosition = () => {
// scrollRef.current.scrollTo({ y: pan.y });
};
return (
<View style={styles.container}>
{/* Container taking up the whole screen, lets us swipe to change pan responder y pos */}
<Animated.View
style={{
position: "absolute",
width: "100%",
height: "100%",
backgroundColor: "rgba(0,255,0,.5)",
}}
{...panResponder.panHandlers}
/>
{/* A animated container that reacts to pan Responder Y pos */}
<Animated.View
style={{
transform: [{ translateY: pan.y }],
}}
>
<ButtonWrapper>
<View style={styles.box} {...panResponder.panHandlers} />
</ButtonWrapper>
</Animated.View>
{/* Here we need the scrollView to be controlled by the Pan Y pos */}
<Animated.ScrollView ref={scrollRef}>
<Content />
</Animated.ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
titleText: {
fontSize: 14,
lineHeight: 24,
fontWeight: "bold",
},
box: {
height: 150,
width: 150,
backgroundColor: "blue",
borderRadius: 5,
},
});

making a virtualized list with a separate file in react

I created a to do list app in app.js and a virtualized list in VirtualizedList.js but none of the virtualized list code is displaying although I imported it into app.js properly.
Here is the VirtualizedList.js code.
import React from 'react';
import { SafeAreaView, View, VirtualizedList, StyleSheet, Text,
StatusBar } from 'react-native';
const DATA = [];
const getItem = (data, index) => ({
id: Math.random().toString(12).substring(0),
title: `Item ${index+1}`
});
const getItemCount = (data) => 50;
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const App = () => {
return (
<SafeAreaView style={styles.container}>
<VirtualizedList
data={DATA}
initialNumToRender={4}
renderItem={({ item }) => <Item title={item.title} />}
keyExtractor={item => item.key}
getItemCount={getItemCount}
getItem={getItem}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: StatusBar.currentHeight,
},
item: {
backgroundColor: '#f9c2ff',
height: 100,
justifyContent: 'center',
marginVertical: 7,
marginHorizontal: 24,
padding: 20,
},
title: {
fontSize: 25,
},
});
export default App;
This is how I imported VirtualizedList into app.js:
import VirtualizedList from '/Users/myname/Applications/todo-
app/src/components/VirtualizedList';
Normally you would export default your list in VirtualizedList.js and you would import them in your App.js (renderer) as a normal object. But I would have to see the code to be sure

The child component doesn't disappear when the height of the parent component is animated to 0

I want to have a dropdown box that could appear and disappear by increase/decrease in its box. Currently it's appearing by having its height increased, but doesn't disappear when the height is decreased. More specifically, the height is being decreased, but the text element, which is the child component, is not disappearing.
The screen component:
import React, { useState } from 'react'
import {
View,
Text,
StyleSheet,
Dimensions,
ScrollView,
SafeAreaView,
} from 'react-native'
import Panel from '../components/help/Panel'
const { width } = Dimensions.get('window')
export default Help = () => {
return (
<SafeAreaView style={styles.container}>
<ScrollView contentContainerStyle={styles.scrollView}>
<Panel title="Question 1" >
<Text> Lorem ipsum dolor sit amet, consectetur adipiscing elit.</Text>
</Panel>
<Panel title="A Panel with long content text">
<Text>Lorem ipsum...</Text>
</Panel>
<Panel title="Another Panel">
<Text>Lorem ipsum dolor sit amet...</Text>
</Panel>
</ScrollView>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
width: width * .90,
alignSelf: 'center',
},
})
Panel.js
import React, { useState } from 'react'
import {
View,
Text,
StyleSheet,
TouchableOpacity,
Animated,
} from 'react-native'
import { moderateScale } from 'react-native-size-matters'
import Icon from "react-native-vector-icons/AntDesign"
export default Panel = ({ title, children }) => {
const [isExpanded, expand] = useState(false)
const [minHeight, setMinHeight] = useState()
const [maxHeight, setMaxHeight] = useState()
const [animation] = useState(new Animated.Value(0))
const _setMinHeight = e => {
setMinHeight(e.nativeEvent.layout.height)
}
const _setMaxHeight = e => {
setMaxHeight(e.nativeEvent.layout.height)
}
const toggle = () => {
let initialValue = isExpanded ? maxHeight + minHeight : minHeight
let finalValue = isExpanded ? minHeight : maxHeight + minHeight
animation.setValue(initialValue)
Animated.spring(animation,{
toValue: finalValue,
duration: 1500,
}).start(() => {
expand(!isExpanded)
})
}
return (
<View style={[styles.container]}>
<TouchableOpacity
style={styles.questionContainer}
onLayout={_setMinHeight}
onPress={toggle}
>
<Text style={styles.questionText}>{title}</Text>
<Icon
name={isExpanded ? "caretup" : "caretdown"}
size={moderateScale(15)}
style={styles.icon}
/>
</TouchableOpacity>
<Animated.View
style={[styles.answerContainer, { height: animation }]}
onLayout={_setMaxHeight}
>
{children}
</Animated.View>
</View>
)
}
const styles = StyleSheet.create({
container : {
backgroundColor: '#fff',
margin:10,
},
questionContainer : {
flexDirection: 'row',
},
questionText: {
flex: 1,
padding: 10,
color:'#2a2f43',
fontWeight:'bold'
},
icon: {
paddingTop: 10,
},
answerContainer: {
padding: 10,
paddingTop: 0,
overflow:'hidden'
}
})
Update
Actually, the height is being unpredictable, which I'm not sure why.
I've been working on your code for a long time
This is a little better
He was acting strangely perhaps because he was updating the state in a circular and uncontrollable way
import React, {Component} from 'react';
import {Animated, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import Icon from 'react-native-vector-icons/index';
import {moderateScale} from 'react-native-size-matters';
export default class PanelClass extends Component {
constructor(props) {
super(props);
this.isExpanded = false;
this.animation = new Animated.Value(15);
}
toggle = () => {
let initialValue = this.isExpanded ? 50 : 15;
let finalValue = this.isExpanded ? 15 : 50;
this.animation.setValue(initialValue);
Animated.spring(this.animation, {
toValue: finalValue,
duration: 1000,
}).start(() => {
this.isExpanded = !this.isExpanded;
});
};
render() {
return (
<View style={[styles.container]}>
<TouchableOpacity
style={styles.questionContainer}
onPress={this.toggle}>
<Text style={styles.questionText}>
{this.props.title}
</Text>
<Icon
name={this.state.isExpanded ? 'caretup' : 'caretdown'}
size={moderateScale(15)}
style={styles.icon}
/>
</TouchableOpacity>
<Animated.View
style={[styles.answerContainer, {height: this.animation}]}
>
{this.props.children}
</Animated.View>
</View>
);
}
}
```

unexpected token when trying to declare a variable inside flatlist in react native

i'm trying to declare an variable inside the FlatList component in React Native
But i get unexpected token, when i do declare it.
const FixturesScreen = ({ navigation }) => (
<ScrollView style={styles.container}>
<FlatList
data={clubData.data.clubs}
renderItem={({ item }) => (
let fixture = item.name //unexpected token
<View>
<View>
<Text style={styles.itemTitle}>{item.name}</Text>
<ScrollView horizontal>
<Text style={styles.listItem}>{fixture}</Text>
</ScrollView>
</View>
</View>
)
}
/>
</ScrollView>
)
here is my full FixturesScreen cdoe
import React from 'react'
import { View, Text, FlatList, ScrollView, StyleSheet } from 'react-native'
import Ionicons from 'react-native-vector-icons/Ionicons'
import clubData from '../../clubData'
const styles = StyleSheet.create({
container: {
backgroundColor: '#4BABF4',
},
itemTitle: {
color: 'black',
fontSize: 20,
marginTop: 20,
marginBottom: 10,
marginLeft: 15,
},
listItem: {
color: '#FFFFFF',
fontSize: 18,
textAlign: 'center',
marginRight: 15,
marginLeft: 15,
backgroundColor: '#77BEF5',
width: 120,
paddingVertical: 10,
},
})
const CURRENTTGAMEWEEK = 30
const i = CURRENTTGAMEWEEK
const nxt1 = i + 1
const nxt2 = nxt1 + 2
const nxt3 = nxt2 + 1
const nxt4 = nxt3 + 1
const nxt5 = nxt4 + 1
// let fixture
// const team = clubData.data.clubs[0].name
// const hTeam = clubData.data.clubs[0].fixtures[0].homeTeam
// const hTeamShort = clubData.data.clubs[0].fixtures[0].homeTeamShort
// const aTeamShort = clubData.data.clubs[0].fixtures[0].awayTeamShort
//
// if (team === hTeam) // working
// fixture = aTeamShort
// else
// fixture = hTeamShort
console.log(`Now is playing ${fixture}`)
const FixturesScreen = ({ navigation }) => (
<ScrollView style={styles.container}>
<FlatList
data={clubData.data.clubs}
renderItem={({ item }) => (
let fixture = item.name
<View>
<View>
<Text style={styles.itemTitle}>{item.name}</Text>
<ScrollView horizontal>
<Text style={styles.listItem}>{fixture}</Text>
</ScrollView>
</View>
</View>
)
}
/>
</ScrollView>
)
FixturesScreen.navigationOptions = {
tabBarTestIDProps: {
testID: 'TEST_ID_HOME',
accessibilityLabel: 'TEST_ID_HOME_ACLBL',
},
tabBarLabel: 'Main',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-home' : 'ios-home-outline'}
size={26}
style={{ color: tintColor }}
/>
),
}
export default FixturesScreen
So basically what i'm trying to do is declare homeTeam, awayTeam and Fixture inside the flatlist, so i can do an if/else conditional rendering inside the flatlist. I can achieve that outside the flatlist component but it is not right, because i can not compare all objects at once.
While using arrow functions () => ('someValue') is a shortcut for () => { return 'someValue'}.
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// equivalent to: (param1, param2, …, paramN) => { return expression; }
// Parentheses are optional when there's only one parameter name:
(singleParam) => { statements }
singleParam => { statements }
// A function with no parameters should be written with a pair of parentheses.
() => { statements }
// Parenthesize the body of function to return an object literal expression:
params => ({foo: bar})
So if you want to run some code before returning a value you should do like below;
const FixturesScreen = ({ navigation }) => (
<ScrollView style={styles.container}>
<FlatList
data={clubData.data.clubs}
renderItem={({ item }) => { //change to curly braces
let fixture = item.name;
// do something here
return (
<View>
<View>
<Text style={styles.itemTitle}>{item.name}</Text>
<ScrollView horizontal>
<Text style={styles.listItem}>{fixture}</Text>
</ScrollView>
</View>
</View>
);
}}
/>
</ScrollView>
)

Resources