title: React native array map insert at beginning
body: <p>I wrote an animated list component:</p>
  
  <pre class="lang-js prettyprint-override"><code>import React, {Component} from 'react';
  import PropType from 'prop-types';
  import * as Animatable from 'react-native-animatable-promise';
  import {FlatList, View} from 'react-native';
  import {observable, action, runInAction} from "mobx"
  import {observer} from 'mobx-react';
  import TransitionGroup, {FadeInOutTransition} from 'react-native-transitiongroup';
  import arrayDiff from 'arraydiff';
  
  class AnimatedListItem extends Component {
  
      static propTypes = {
          animationOut: PropType.string.isRequired,
          animationIn: PropType.string.isRequired,
          duration: PropType.number.isRequired
      };
  
      tempHeight = 0;
      locked = false;
  
      componentDidAppear(callback) {
          this.componentWillEnter(callback);
      }
  
      componentDidEnter(callback) {
          this.refs.Item[this.props.animationIn](this.props.duration).then(() =&gt; callback());
      }
  
      componentWillLeave(callback) {
          this.locked = true;
          this.refs.Item.stopAnimation();
          this.refs.Item.transition({height: this.tempHeight, opacity: 1, scale: 1}, {height: 0, opacity: 0, scale: 0}, this.props.duration, 'ease').then(callback).catch(console.error);
          //this.refs.Item[this.props.animationOut](this.props.duration).then(() =&gt; callback());
      }
  
      _onLayout(event) {
          const {height} = event.nativeEvent.layout;
          if (!this.locked) this.tempHeight = height;
      }
  
      render() {
          return (&lt;Animatable.View ref='Item' onLayout={this._onLayout.bind(this)}&gt;
              {this.props.children}
          &lt;/Animatable.View&gt;);
      }
  
  }
  
  @observer
  class AnimatedList extends Component {
  
      static propTypes = {
          data: PropType.array.isRequired,
          renderItem: PropType.func.isRequired,
          keyExtractor: PropType.func.isRequired,
          inAnimation: PropType.string.isRequired,
          outAnimation: PropType.string.isRequired,
          style: PropType.any,
          duration: PropType.number,
          delay: PropType.number
      };
  
      @observable keyExtractor = this.props.keyExtractor;
      @observable data = [];
      @observable duration = this.props.duration || 1000;
      @observable outAnimation = this.props.outAnimation;
      @observable inAnimation = this.props.inAnimation;
      _renderItem = this.props.renderItem;
      delay = this.props.delay || 100;
  
      queue;
      actionIsRunning = false;
  
      componentDidMount() {
          this.setProps(this.props);
      }
  
      componentWillReceiveProps(props) {
          this.setProps(props);
      }
  
      setProps(props) {
          requestAnimationFrame(() =&gt; {
              if (this.actionIsRunning) {
                  this.queue = props;
                  return;
              }
              this.queue = null;
              this.actionIsRunning = true;
              runInAction(() =&gt; {
                  this.duration = props.duration || 1000;
                  this.outAnimation = props.outAnimation;
                  this.inAnimation = props.inAnimation;
                  this.delay = props.delay;
                  this.keyExtractor = props.keyExtractor;
              });
              const differences = arrayDiff(this.data.toJS(), props.data.toJS(), (a, b) =&gt; {
                  const aKey = this.keyExtractor(a);
                  const bKey = this.keyExtractor(b);
                  return aKey === bKey;
              });
              console.log("ADIFF: " + JSON.stringify(differences));
              this.applyDifferences(differences).then(() =&gt; {
                  console.log("NEWLIST: " + JSON.stringify(this.data));
                  this.actionIsRunning = false;
                  if (this.queue) this.setProps.bind(this)(this.queue);
              }).catch(e =&gt; console.error(e));
          });
      }
  
      async applyDifferences(differences) {
          for (let diff of differences) {
              if (!diff.type) continue;
              await new Promise((resolve) =&gt; requestAnimationFrame(resolve));
              if (diff.type === 'remove' &amp;&amp; diff.index !== undefined &amp;&amp; diff.howMany !== undefined) {
                  runInAction(() =&gt; {
                      this.data.splice(diff.index, diff.howMany);
                  });
              }
              if (diff.type === 'move' &amp;&amp; diff.from !== undefined &amp;&amp; diff.to !== undefined) {
                  runInAction(() =&gt; {
                      moveInThisArray(this.data, diff.from, diff.to);
                  });
              }
              if (diff.type === 'insert' &amp;&amp; diff.index !== undefined &amp;&amp; Array.isArray(diff.values)) {
                  const argArray = [diff.index, 0];
                  for (let value of diff.values) {
                      argArray.push(value);
                  }
                  runInAction(() =&gt; {
                      this.data.splice.apply(this.data, argArray);
                  });
              }
              await new Promise((resolve) =&gt; setTimeout(resolve, this.delay));
          }
          await new Promise((resolve) =&gt; setTimeout(resolve, this.duration));
      }
  
  
      /**
       * @typedef {Object} FlatListRenderInfo
       * @property {Object} item
       * @property {Number} index
       * @property {Object} separators
       */
  
      /**
       *
       * @param {FlatListRenderInfo} info
       */
      renderItem(info) {
          //console.log(this.keyExtractor(info.item));
          return (
              &lt;AnimatedListItem animationOut={this.outAnimation} animationIn={this.inAnimation} duration={this.duration}
                                key={this.keyExtractor(info.item)}&gt;
                  {this._renderItem(info)}
              &lt;/AnimatedListItem&gt;);
      }
  
      render() {
          return (&lt;TransitionGroup&gt;
              {this.data.toJS().map((item, index) =&gt; {
                  return this.renderItem({
                      item: item,
                      index: index,
                      separators: {}
                  });
              })}
          &lt;/TransitionGroup&gt;)
      }
  
  }
  
  function moveInThisArray(arr, old_index, new_Index) {
      if (new_Index &gt;= arr.length) {
          let k = new_Index - arr.length;
          while ((k--) + 1) {
              arr.push(undefined);
          }
      }
      arr.splice(new_Index, 0, arr.splice(old_index, 1)[0]);
      return arr;
  }
  
  export default AnimatedList;
  </code></pre>
  
  <p>The most of my code works as expected. But I have a little problem, if I add an element at the beginning of the array, it will render at the end of my list. I think maybe my usage of <code>Array.map</code> is wrong. There is no problem with the array, if I print the array to the console, it has the right order. I already noticed this problem in my last problem, but ignored it because in my last project it dosen't mattered in which order the elements were, but this time it matters. Is there an alternative to use instead <code>Array.map</code> to solve the problem? Or what should I do?</p>