title: React Native - Animating the Screen to its MapView.Marker
body: <p>My goal is to animate the screen to each MapView.Marker when swipping to each Card (Animated.ScrollView) . Already tried this and it worked but now I did some changes to my codes because I added React Redux.</p>
  
  <p>I think might be the problem is about the pointing out the React Redux State or the Key, because I get warning about Key. It says:</p>
  
  <blockquote>
    <p>Warning: Each child  in a list should have unique "key" prop.</p>
  </blockquote>
  
  <p>I want to animate the screen to each MapView.Marker like this:</p>
  
  <p><a href="https://i.stack.imgur.com/n6j1k.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/n6j1k.png" alt="enter image description here"></a></p>
  
  <p>Here are my codes: </p>
  
  <pre><code>componentWillMount() {
  this.index = 0;
  this.animation = new Animated.Value(0);
  }
  
  componentDidMount() {
  // We should detect when scrolling has stopped then animate
  // We should just debounce the event listener here
  this.animation.addListener(({ value }) =&gt; {
    let index = Math.floor(value / CARD_WIDTH + 0.3); // animate 30% away from landing on the next item
    if (index &gt;= this.props.events.length) {
      index = this.props.events.length - 1;
    } else {
      return null;
    }
    if (index &lt;= 0) {
      index = 0;
    } else {
      return null;
    }
  
    clearTimeout(this.regionTimeout);
    this.regionTimeout = setTimeout(() =&gt; {
      if (this.index !== index) {
        this.index = index;
        const { focusedLocation } = this.props.events.location.value.latitude &amp;&amp; this.props.events.location.value.longitude[index];
        this.map.animateToRegion(
          {
            ...focusedLocation,
            latitudeDelta: this.state.focusedLocation.latitudeDelta,
            longitudeDelta: this.state.focusedLocation.longitudeDelta,
          },
          350
        );
      }
    }, 10);
  });
  }
  
  render() {
  //For the Scroll View Card
  const interpolations = this.props.events.map((marker, index) =&gt; {
    const inputRange = [
      (index - 1) * CARD_WIDTH,
      index * CARD_WIDTH,
      ((index + 1) * CARD_WIDTH),
    ];
    const scale = this.animation.interpolate({
      inputRange,
      outputRange: [1, 2.5, 1],
      extrapolate: "clamp",
    });
    const opacity = this.animation.interpolate({
      inputRange,
      outputRange: [0.35, 1, 0.35],
      extrapolate: "clamp",
    });
    return { scale, opacity };
  });
  
  return(
    &lt;View style={styles.container}&gt;
      {/* &lt;StatusBar backgroundColor={'transparent'} translucent={true}/&gt; */}
      &lt;MapView
        style={styles.container}
        initialRegion={this.state.focusedLocation}
        onPress={this.pickLocationHandler}
        showsUserLocation={true}
        ref={ref =&gt; this.map = ref} //For animating map movement
      &gt;
        {userMarker}
        {this.props.events.map((marker, index) =&gt; {
          if(marker.location) {
            const scaleStyle = {
              transform: [
                {
                  scale: interpolations[index].scale,
                },
              ],
            };
            const opacityStyle = {
              opacity: interpolations[index].opacity,
            };
            return (
              &lt;MapView.Marker key={index} coordinate={marker.location}&gt;
                &lt;Animated.View style={[styles.markerWrap, opacityStyle]}&gt;
                  &lt;Animated.View style={[styles.ring, scaleStyle]} /&gt;
                    &lt;View style={styles.marker} /&gt;
                &lt;/Animated.View&gt;
              &lt;/MapView.Marker&gt;
            );
          } else {
            return null;
          }
        })}
      &lt;/MapView&gt;
      &lt;Animated.ScrollView
        horizontal
        scrollEventThrottle={1}
        pagingEnabled={true}
        showsHorizontalScrollIndicator={false}
        snapToInterval={snapInterval}
        onScroll={Animated.event(
          [
            {
              nativeEvent: {
                contentOffset: {
                  x: this.animation,
                },
              },
            },
          ],
          { useNativeDriver: true }
        )}
        style={styles.scrollView}
        contentContainerStyle={styles.endPadding}
      &gt;
        &lt;FlatList
        keyExtractor={this._keyExtractor}
        horizontal
        data={this.props.events}
        renderItem={(info) =&gt; (
          &lt;TouchableOpacity onPress={() =&gt; this.itemSelectedHandler(info.item.key)}&gt;
            &lt;View style={styles.card} key={info.item.key}&gt;
              &lt;Image
                source={info.item.image}
                style={styles.cardImage}
                resizeMode="cover"
              /&gt;
              &lt;View style={styles.textContent}&gt;
                &lt;Text numberOfLines={1} style={styles.cardtitle}&gt;{info.item.name}&lt;/Text&gt;
                &lt;Text numberOfLines={1} style={styles.cardDescription}&gt;
                  {info.item.description}
                &lt;/Text&gt;
              &lt;/View&gt;
            &lt;/View&gt;
          &lt;/TouchableOpacity&gt;
        )}
      /&gt;
      &lt;/Animated.ScrollView&gt;
      &lt;TouchableOpacity onPress={this.getLocationHandler} style={styles.iconContainer}&gt;
        &lt;Icon name="md-locate" size={30} color="blue"/&gt;
      &lt;/TouchableOpacity&gt;
    &lt;/View&gt;
  );
  }
  }
  
  const mapStateToProps = state =&gt; {
  return {
   events: state.events.events
  };
  };
  
  export default connect(mapStateToProps)(EventMap);
  </code></pre>
  
  <p>My codes for React Redux: </p>
  
  <p>../../reducers/events.js:</p>
  
  <pre><code>const reducer = (state = initialState, action) =&gt; {
  switch (action.type) {
  case ADD_EVENT:
    return {
      ...state,
      events: state.events.concat({
        key:  `${Math.random()}`,
        name: action.eventName,
        description: action.eventDescription,
        location: action.location,
        image: {
          uri: "https://c1.staticflickr.com/5/4096/4744241983_34023bf303_b.jpg"
        }
      })
    };
  </code></pre>