Igor William
Igor William

Reputation: 93

Problem in sync carrousel images with scrollview in React native

I have many problems using this implementation to sync the text and a carrousel images with scrollview in React Native. I try many options to fix this like setTimeout and contentOffset.

The problem is the first render not call the scrollTo and this unsynchronize the text and image showed.

I found this issue in React Native https://github.com/facebook/react-native/issues/6849, but i can't extract a solution in this. Someone can help me?

import * as React from "react";
import { View, Text,ScrollView, useWindowDimensions } from "react-native";

const data = [
  {
      color: 'red'
  },
  {
      color: 'blue'
  },
  {
      color: 'black'
  },
  {
      color: 'green'
  }
]

export default function App() {

  const scrollViewRef = React.useRef();
  const { width } = useWindowDimensions();
  const [index, setIndex] = React.useState(0);

  const offsetContent = (offset) => {
      scrollViewRef.current.scrollTo({ x: offset, animated: false });
  };

  const autoScroll = () => {
    const size = data.length - 1;
    setIndex(size === index ? 0 : index + 1);

    const offset = width * index;

    offsetContent(offset);

    console.log(`${size} ${index} ${offset}`);
  };


  React.useEffect(() => {
    const timer = setTimeout(autoScroll, 3000);

    return () => clearTimeout(timer);
  });

  return (
    <View
      style={{
        justifyContent: "center",
        alignItems: "center",
      }}
    >

      <ScrollView
        ref={scrollViewRef}
        horizontal
        showsHorizontalScrollIndicator={false}
        contentContainerStyle={{ height: width / 1.5 }}
        pagingEnabled
        contentOffset={{ x: 380, y: 0 }}
      >
        {data.map((item) => (
          <View key={item.color} style={{width, height: 280, backgroundColor: item.color}} />
        ))}
      </ScrollView>


      <Text>{data[index].color}</Text>
    </View>
  );
}

Upvotes: 0

Views: 205

Answers (1)

Leri Gogsadze
Leri Gogsadze

Reputation: 3093

Look!!

const autoScroll = () => {
    const size = data.length - 1;
    setIndex(size === index ? 0 : index + 1);

    const offset = width * index;

    offsetContent(offset);
    // Here you calculate offset based on index..
    // When you increase index and update the state, you need another hook do detect when this index is updated and then calculate an offset.
}


// Add this hook and calculate an offset here and call offsetContent function.
React.useEffect(() => {
    const offset = width * index;

    offsetContent(offset);
}, [index]);

At the first timeOut, you updated index and thought it was 1 but actually, it was 0 again when you calculated an offset that's why the scroll didn't change.

Upvotes: 1

Related Questions