在 react-native 中创建一个滑块
Creating a slider in react-native
我正在通过关注 YouTube 视频创建一个反应本机滑块,但这是在基于 class 的组件中,我使用的是基于功能的组件。一切正常,但卡在一个地方。
有人帮我把这段代码转换成功能组件:
Class 基于组件
this.setState(prev=> ({ selectedIndex: prev.selectedIndex === this.props.images.length-1 ? 0 : prev.selectedIndex + 1}),
()=>{
this.scrollRef.current.scrollTo({
animate: true,
y: 0,
x: ScreenWidth * this.state.selectedIndex
})
})
我想将上面的代码转换为函数,但无法正常工作有人告诉我我做错了什么
setInterval(()=>{
setImgActive(imgActive+1)
sliderCustom.current.scrollTo({
animated:true,
y:0,
x:width*imgActive
})
},6000)
我的完整代码
import React, { useState, useEffect, useRef, useCallback } from "react";
import {
ActivityIndicator,
Image,
StyleSheet,
Text,
View,
Platform,
FlatList,
TouchableOpacity,
ScrollView,
Dimensions
} from "react-native";
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from "react-native-responsive-screen";
// color
import colors from "../colors/colors";
// api
import { getBannersApi } from "../api/apis";
import {media} from "../api/config.json"
// Carousel
import { FlatListSlider } from "react-native-flatlist-slider";
import Carousel,{ ParallaxImage } from 'react-native-snap-carousel';
const {width, height} = Dimensions.get('window')
const Preview = ({
item,
onPress,
index,
}) => {
return(
<TouchableOpacity
style={[styles.videoContainer,{
// marginLeft:index == 0 ? wp('2'): 0,
}]}
>
<View style={[styles.imageContainer, styles.shadow]}>
<Image
style={{height:hp('22'), width:wp('90'), borderRadius:10,}}
source={item.banner}
/>
</View>
</TouchableOpacity>
)
}
const SliderCarouselFlat = () => {
const [banners, setBanners] = useState([])
const [activeIndex, setActiveIndex] = useState(0)
const [imgActive, setImgActive] = useState(0)
const [load, setLoad] = useState(false)
const slider = useRef()
const caro = useRef()
const sliderCustom = useRef()
// console.log('Banners State', banners)
const images = [
{
banner:require('../images/banner.png'),
},
{
banner:require('../images/bannert.png'),
},
{
banner:require('../images/bannert.png'),
},
{
banner:require('../images/bannert.png'),
},
];
useEffect(()=>{
getBanners()
if(load == true){
setInterval(()=>{
setImgActive(imgActive+1)
sliderCustom.current.scrollTo({
animated:true,
y:0,
x:width*imgActive
})
},6000)
}
},[])
// API CALL
const getBanners =async () =>{
try{
const {data} =await getBannersApi()
if(data.status == true){
setBanners(data)
setLoad(true)
}
}catch(e){
console.log(e)
}
}
const _renderItem= ({item,index})=>{
return (
<View>
<Image
style={{height:hp('22'), width:wp('90'), borderRadius:10,}}
source={item.banner}
/>
</View>
)
}
const setSelIndex = (event) =>{
const viewSize= event.nativeEvent.layoutMeasurement.width;
const contentOffset = event.nativeEvent.contentOffset.x;
const selIndex = Math.floor(contentOffset/viewSize)
setImgActive(selIndex)
}
return (
<View style={styles.container}>
<View style={styles.wrap} >
{
load == false?
<ActivityIndicator size="small" color={colors.primary} />
:
<View>
<ScrollView
ref={sliderCustom}
onMomentumScrollEnd={setSelIndex}
showsHorizontalScrollIndicator={false}
pagingEnabled
horizontal
autoScroll
style={styles.wrap}
>
{
banners.all_banners.map((item,index)=>{
return(
<View >
<Image
source={{uri:item.banner}}
resizeMode="contain"
style={{height:hp('22'), width:wp('90'), borderRadius:10, marginHorizontal:index == 0 ? wp(2):wp(4)}}
/>
</View>
)
})
}
</ScrollView>
<View style={styles.wrapDots } >
{
banners.all_banners.map((item, index)=>(
<Text
key={index}
style={imgActive==index?styles.dotActive:styles.dot }
>
●
</Text>
))
}
</View>
</View>
}
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexGrow: 1,
},
videoContainer:{
// paddingHorizontal:hp('2'),
},
wrap:{
},
wrapDots:{
position:'absolute',
bottom:0,
flexDirection:'row',
alignSelf:'center'
},
dotActive:{
margin:2,
color:'#ffffff',
},
dot:{
margin:2,
color:'#ffffff80'
}
});
export default SliderCarouselFlat;
您可以轻松地将基于 class 的组件转换为功能结构,并与之相对。
只需要注意和一些基本规则:
setInterval(() => {
setImgActive(prevSTate => ({
selectedIndex: prevState.selectedIndex === props.images.length-1 ? 0 : prevState.selectedIndex + 1
}))
slider .current.scrollTo({
animated:true,
y:0,
x:width*imgActive
})
}, 60000)
我正在通过关注 YouTube 视频创建一个反应本机滑块,但这是在基于 class 的组件中,我使用的是基于功能的组件。一切正常,但卡在一个地方。 有人帮我把这段代码转换成功能组件: Class 基于组件
this.setState(prev=> ({ selectedIndex: prev.selectedIndex === this.props.images.length-1 ? 0 : prev.selectedIndex + 1}),
()=>{
this.scrollRef.current.scrollTo({
animate: true,
y: 0,
x: ScreenWidth * this.state.selectedIndex
})
})
我想将上面的代码转换为函数,但无法正常工作有人告诉我我做错了什么
setInterval(()=>{
setImgActive(imgActive+1)
sliderCustom.current.scrollTo({
animated:true,
y:0,
x:width*imgActive
})
},6000)
我的完整代码
import React, { useState, useEffect, useRef, useCallback } from "react";
import {
ActivityIndicator,
Image,
StyleSheet,
Text,
View,
Platform,
FlatList,
TouchableOpacity,
ScrollView,
Dimensions
} from "react-native";
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from "react-native-responsive-screen";
// color
import colors from "../colors/colors";
// api
import { getBannersApi } from "../api/apis";
import {media} from "../api/config.json"
// Carousel
import { FlatListSlider } from "react-native-flatlist-slider";
import Carousel,{ ParallaxImage } from 'react-native-snap-carousel';
const {width, height} = Dimensions.get('window')
const Preview = ({
item,
onPress,
index,
}) => {
return(
<TouchableOpacity
style={[styles.videoContainer,{
// marginLeft:index == 0 ? wp('2'): 0,
}]}
>
<View style={[styles.imageContainer, styles.shadow]}>
<Image
style={{height:hp('22'), width:wp('90'), borderRadius:10,}}
source={item.banner}
/>
</View>
</TouchableOpacity>
)
}
const SliderCarouselFlat = () => {
const [banners, setBanners] = useState([])
const [activeIndex, setActiveIndex] = useState(0)
const [imgActive, setImgActive] = useState(0)
const [load, setLoad] = useState(false)
const slider = useRef()
const caro = useRef()
const sliderCustom = useRef()
// console.log('Banners State', banners)
const images = [
{
banner:require('../images/banner.png'),
},
{
banner:require('../images/bannert.png'),
},
{
banner:require('../images/bannert.png'),
},
{
banner:require('../images/bannert.png'),
},
];
useEffect(()=>{
getBanners()
if(load == true){
setInterval(()=>{
setImgActive(imgActive+1)
sliderCustom.current.scrollTo({
animated:true,
y:0,
x:width*imgActive
})
},6000)
}
},[])
// API CALL
const getBanners =async () =>{
try{
const {data} =await getBannersApi()
if(data.status == true){
setBanners(data)
setLoad(true)
}
}catch(e){
console.log(e)
}
}
const _renderItem= ({item,index})=>{
return (
<View>
<Image
style={{height:hp('22'), width:wp('90'), borderRadius:10,}}
source={item.banner}
/>
</View>
)
}
const setSelIndex = (event) =>{
const viewSize= event.nativeEvent.layoutMeasurement.width;
const contentOffset = event.nativeEvent.contentOffset.x;
const selIndex = Math.floor(contentOffset/viewSize)
setImgActive(selIndex)
}
return (
<View style={styles.container}>
<View style={styles.wrap} >
{
load == false?
<ActivityIndicator size="small" color={colors.primary} />
:
<View>
<ScrollView
ref={sliderCustom}
onMomentumScrollEnd={setSelIndex}
showsHorizontalScrollIndicator={false}
pagingEnabled
horizontal
autoScroll
style={styles.wrap}
>
{
banners.all_banners.map((item,index)=>{
return(
<View >
<Image
source={{uri:item.banner}}
resizeMode="contain"
style={{height:hp('22'), width:wp('90'), borderRadius:10, marginHorizontal:index == 0 ? wp(2):wp(4)}}
/>
</View>
)
})
}
</ScrollView>
<View style={styles.wrapDots } >
{
banners.all_banners.map((item, index)=>(
<Text
key={index}
style={imgActive==index?styles.dotActive:styles.dot }
>
●
</Text>
))
}
</View>
</View>
}
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexGrow: 1,
},
videoContainer:{
// paddingHorizontal:hp('2'),
},
wrap:{
},
wrapDots:{
position:'absolute',
bottom:0,
flexDirection:'row',
alignSelf:'center'
},
dotActive:{
margin:2,
color:'#ffffff',
},
dot:{
margin:2,
color:'#ffffff80'
}
});
export default SliderCarouselFlat;
您可以轻松地将基于 class 的组件转换为功能结构,并与之相对。
只需要注意和一些基本规则:
setInterval(() => {
setImgActive(prevSTate => ({
selectedIndex: prevState.selectedIndex === props.images.length-1 ? 0 : prevState.selectedIndex + 1
}))
slider .current.scrollTo({
animated:true,
y:0,
x:width*imgActive
})
}, 60000)