title: React-native FlatList not rerendering row when props change
body: <p>I'm having an issue with the new FlatList component. Specifically, it does not rerender it's rows, even though props that the row is dependent on changes. </p>
  
  <hr>
  
  <p>The FlatList docs says that:</p>
  
  <blockquote>
    <p>This is a PureComponent which means that it will not re-render if
    props remain shallow- equal. Make sure that everything your renderItem
    function depends on is passed as a prop that is not === after updates,
    otherwise your UI may not update on changes. This includes the data
    prop and parent component state.</p>
  </blockquote>
  
  <p><strong>THE QUESTION</strong></p>
  
  <p>However, seeing as I change an ID of the selectedCategory item - the prop that should indicate whether the row is 'selected' or not - I believe that the props should rerender. Am I mistaken?</p>
  
  <p>I checked the 'componentWillReceiveProps' methods of both the list and row components, and the list receives the update just fine, but the row's lifecycle method is never called. </p>
  
  <p>If I include a random, useless boolean state value in the list component, and switch it back and forth when the props update, it works - but I don't know why?</p>
  
  <pre><code>state = { updated: false };
  
  componentWillReceiveProps(nextProps) {
    this.setState(oldstate =&gt; ({
      updated: !oldstate.updated,
    }));
  }
  
  &lt;FlatList
    data={this.props.items.allAnimalCategories.edges}
    renderItem={this._renderRow}
    horizontal={true}
    keyExtractor={(item, index) =&gt; item.node.id}
    randomUpdateProp={this.state.updated}
  /&gt;
  </code></pre>
  
  <hr>
  
  <p><strong>THE CODE</strong></p>
  
  <p>The structure of my code is this: I have a container component with all the logic and state, which contains a FlatList component (presentational, no state), which again contains a custom presentational row.</p>
  
  <pre><code>Container
    Custom list component that includes the FlatList component
    (presentational, stateless) and the renderRow method
      Custom row (presentational, stateless)
  </code></pre>
  
  <p>The container includes this component:</p>
  
  <pre><code> &lt;CustomList
     items={this.props.viewer}
     onCategoryChosen={this._onCategoryChosen}
     selectedCategory={this.state.report.selectedCategory}
   /&gt;
  </code></pre>
  
  <p>CustomList:</p>
  
  <pre><code>class CustomList extends Component {
    _renderRow = ({ item }) =&gt; {
      return (
        &lt;CustomListRow
          item={item.node}
          selectedCategory={this.props.selectedCategory}
          onPressItem={this.props.onCategoryChosen}
        /&gt;
      );
    };
  
    render() {
      return (
        &lt;View style={_styles.container}&gt;
          &lt;FlatList
            data={this.props.items.categories.edges}
            renderItem={this._renderRow}
            horizontal={true}
            keyExtractor={(item, index) =&gt; item.node.id}
            randomUpdateProp={this.state.updated}
          /&gt;
        &lt;/View&gt;
      );
    }
  </code></pre>
  
  <p>}</p>
  
  <p>(data comes from Relay)</p>
  
  <p>Finally the row:</p>
  
  <pre><code>render() {
      const idsMatch = this.props.selectedCategory.id == this.props.item.id;
      return (
        &lt;TouchableHighlight onPress={this._onItemPressed}&gt;
          &lt;View style={_styles.root}&gt;
            &lt;View style={[
                _styles.container,
                { backgroundColor: this._getBackgroundColor() },
              ]}&gt;
              {idsMatch &amp;&amp;
                &lt;Image
                  style={_styles.icon}
                  source={require('./../../res/img/asd.png')}
                /&gt;}
              {!idsMatch &amp;&amp;
                &lt;Image
                  style={_styles.icon}
                  source={require('./../../res/img/dsa.png')}
                /&gt;}
              &lt;Text style={_styles.text}&gt;
                {capitalizeFirstLetter(this.props.item.name)}
              &lt;/Text&gt;
            &lt;/View&gt;
            &lt;View style={_styles.bottomView}&gt;
              &lt;View style={_styles.greyLine} /&gt;
            &lt;/View&gt;
          &lt;/View&gt;
        &lt;/TouchableHighlight&gt;
      );
    }
  </code></pre>
  
  <p>The row is not that interesting, but I included it to show that it is entirely stateless and dependent on it's parents props. </p>
  
  <p>The state is updated like so:</p>
  
  <pre><code>_onCategoryChosen = category =&gt; {
      var oldReportCopy = this.state.report;
      oldReportCopy.selectedCategory = category;
      this.setState(Object.assign({}, this.state, { report: oldReportCopy }));
    };
  </code></pre>
  
  <p>State looks like this:</p>
  
  <pre><code>state = {
      ...
      report: defaultStateReport,
    };
  
  const defaultStateReport = {
    selectedCategory: {
      id: 'some-long-od',
      name: '',
    },
    ...
  };
  </code></pre>
  
  <hr>