react-native-snap-carousel无法正确渲染

时间:2019-09-05 01:10:32

标签: javascript reactjs react-native react-native-snap-carousel

问题摘要

我正在使用react-native-snap-carousel,并且渲染不正确。它仅在被刷过后才呈现,我需要在屏幕最初呈现时呈现。当我将屏幕分配给BottomTabNavigator的初始路线或React导航中的Stack Navigator中的初始路线时,轮播会完美呈现。当我在Stack Navigator中将完全相同的屏幕分配给任何其他路线时,只有在我滑动轮播时,它才会渲染轮播。

我需要使用带有轮播的屏幕作为我的Stack Navigator中的第二条路线,但我不知道如何使其正常工作。

我尝试过的事情

  1. 我尝试将所有其他内容都移出屏幕
  2. 我还尝试过从头开始创建新屏幕。
  3. 我已经将屏幕测试为Stack Navigator中的初始路线,并且 它工作正常,但当旋转木马时仍无法渲染 屏幕加载。
  4. 我也尝试过切换到基于类的react组件, 没有帮助。

代码

带有旋转木马的组件

import React, { useState } from "react";
import { View, Text } from "react-native";
import { useDispatch } from "react-redux";
import styles from "./StatSelectorStartComp.style";
import HeaderText from "~/app/Components/HeaderText/HeaderText";
import Carousel from "react-native-snap-carousel";
import LargeButton from "~/app/Components/Buttons/LargeButton/LargeButton";
import NavigationService from "~/app/services/NavigationService";
import { saveStartCompStatCategory } from "~/app/Redux/actions/dailyCompActions";

const StatSelectorStartComp = ({}) => {
  const dispatch = useDispatch();
  const ENTRIES1 = ["Kills", "Wins", "K/D", "Win %"];
  const [selectedStat, setSelectedStat] = useState(ENTRIES1[0]);

  const _renderItem = ({ item, index }) => {
    return (
      <View style={styles.slide}>
        <Text style={styles.compSelectStatCarousel}>{item}</Text>
      </View>
    );
  };

  return (
    <View style={styles.container}>
      <View style={styles.headerTextView}>
        <HeaderText header={"Configure Competition"} />
      </View>
      <Text style={styles.h5Secondary}> Which stat will you track?</Text>
      <View style={styles.selectStatView}>
        <Text style={styles.mediumGreyedOut}>Most {selectedStat} Wins</Text>
        <Carousel
          ref={c => {
            _carousel = c;
          }}
          data={ENTRIES1}
          renderItem={_renderItem}
          sliderWidth={375}
          itemWidth={100}
          onSnapToItem={index => {
            setSelectedStat(ENTRIES1[index]);
          }}
        />
      </View>
      <View style={styles.buttonView}>
        <LargeButton
          onPress={() => {
            dispatch(saveStartCompStatCategory(selectedStat));
            NavigationService.navigate("CompAddFriends");
          }}
          buttonText="Add Friends"
        />
      </View>
    </View>
  );
};

export default StatSelectorStartComp;

带有轮播的组件样式

import { StyleSheet } from "react-native";
import { backgroundColor } from "~/app/Constants";
import {
  h5Secondary,
  mediumGreyedOut,
  compSelectStatCarousel
} from "~/app/FontConstants";

export default StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "space-between",
    backgroundColor
  },
  headerTextView: {
    flex: 1
  },
  h5Secondary,
  selectStatView: {
    flex: 3
  },
  mediumGreyedOut,
  compSelectStatCarousel,
  buttonView: {
    flex: 2
  }
});

反应导航配置

const StartCompStack = createStackNavigator({
  StartFriendsComp: {
    screen: StartFriendsComp
  },
  StatSelectorStartComp: {
    screen: CarouselTest
  },
  CompAddFriends: {
    screen: CompAddFriends
  },
  FinalCompScreen: {
    screen: FinalCompScreen
  }
});

const ProfileStack = createStackNavigator({
  Profile: {
    screen: ProfileScreen
  },
  Settings: {
    screen: SettingsScreen
  }
});

const BottomTabNav = createBottomTabNavigator(
  {
    Home: {
      screen: HomeScreen
    },
    Competitions: {
      screen: Competitions
    },
    StartComp: {
      screen: StartCompStack,
      navigationOptions: () => ({
        tabBarVisible: false
      })
    },
    CompScreen: {
      screen: CompScreen
    },
    Friends: {
      screen: FriendsDrawer
    },
    Profile: {
      screen: ProfileStack
    },
    FacebookFriendsList
  },
  {
    tabBarComponent: CustomTabNav,
    initialRouteName: "Home" 
  }
);

概述问题的图片

屏幕加载时,轮播未呈现 When screen loads, carousel not rendered

刷卡轮播后 After swiping on carousel

5 个答案:

答案 0 :(得分:3)

我们的项目也遇到了同样的问题,有一点技巧可以帮助我们。我们已将默认加载状态设置为true,并在componentDidMount中将状态设置为false以显示Carousel

尝试一下,可能会对您有所帮助

state = { loading: true };

  componentDidMount() {
    setTimeout(() => {
      this.setState({ loading: false });
    }, 10);
  }
  render() {
    if(this.state.loading) {
      return null;
    }

    // return component render which contain Carousel
    ......... 
  }

答案 1 :(得分:3)

我通过简单地使用 removeClippedSubviews={false}

解决了它

答案 2 :(得分:1)

有一个实验性配置(当前为v3.8.4)-removeClippedSubviews-默认情况下设置为true。将其设置为false可以解决我的问题。

我强烈建议您不要使用延迟,因为它不是确定性的,不会因设备而异。

感谢@auticcat在评论中写道。

答案 3 :(得分:0)

<Carousel
          ref={c => {
            _carousel = c;
          }}
          data={ENTRIES1}
          renderItem={_renderItem}
          sliderWidth={375}
          itemWidth={100}
          onSnapToItem={index => {
            setSelectedStat(ENTRIES1[index]);
          }}
        />
      </

我认为问题出在这里,给出静态的高度和宽度。尝试动态计算高度和宽度,然后显示出来。动态是指计算设备的高度和宽度,然后对其进行计算。

答案 4 :(得分:0)

您可以创建自己的自定义轮播。轮播最终结果如下所示-

enter image description here

     goToNextPage = () => {
    const childlenth = this.getCustomData().length;
    selectedIndex = selectedIndex + 1;
    this.clearTimer();
    if (selectedIndex === childlenth) {
        this.scrollRef.current.scrollTo({ offset: 0, animated: false, nofix: true });
        selectedIndex = 1;
    }
    this.scrollRef.current.scrollTo({
        animated: true,
        x: this.props.childWidth * selectedIndex,
    });
    this.setUpTimer();
}

// pushing 1st element at last
 getCustomData() {
    const {data} = this.props;
    const finaldata = [];
    finaldata.push(...data);
    finaldata.push(data[0]);
    return finaldata;
}

这是循环轮播背后使用的主要逻辑。 在这里,我们再次推送列表中的第一个项目,然后当滚动到达最后一个位置时,我们使滚动视图滚动到第一个位置,因为第一个和最后一个元素现在相同,我们滚动到第一个位置,动画如下< /p>

this.scrollRef.current.scrollTo({ offset: 0, animated: false, nofix: true });

如需进一步参考,请访问提供的链接。

https://goel-mohit56.medium.com/custom-horizontal-auto-scroll-looped-carousel-using-scrollview-42baa5262f95