React-native FlatList does not reverse the string when changing props

I am having a problem with the new FlatList component. In particular, it does not overwrite lines, even if the props depend on line changes.


FlatList docs say that:

This is a PureComponent, which means that it will not re-render if the props remain shallow. Make sure that all your renderItem function depends on being passed as a support, which is not === after updates, otherwise your user interface may not be updated when changes are made. This includes prop and parent component data.

QUESTION

However, seeing how I change the identifier of the selected category object - an alert that should indicate whether the row is selected or not, I believe that the props should be repeated. Am I mistaken?

I tested componentWillReceiveProps methods for both list components and strings, and the list gets updated just fine, but the string lifecycle method is never called.

If I turn on a random, useless logical state value in the list component and switch it back and forth when updating the attribute, it works - but I don’t know why?

state = { updated: false };

componentWillReceiveProps(nextProps) {
  this.setState(oldstate => ({
    updated: !oldstate.updated,
  }));
}

<FlatList
  data={this.props.items.allAnimalCategories.edges}
  renderItem={this._renderRow}
  horizontal={true}
  keyExtractor={(item, index) => item.node.id}
  randomUpdateProp={this.state.updated}
/>

THE CODE

The structure of my code is as follows: I have a container component with all the logic and state that contains the FlatList component (presentation, stateless), which again contains a custom presentation string.

Container
  Custom list component that includes the FlatList component
  (presentational, stateless) and the renderRow method
    Custom row (presentational, stateless)

The container includes this component:

 <CustomList
   items={this.props.viewer}
   onCategoryChosen={this._onCategoryChosen}
   selectedCategory={this.state.report.selectedCategory}
 />

CustomList:

class CustomList extends Component {
  _renderRow = ({ item }) => {
    return (
      <CustomListRow
        item={item.node}
        selectedCategory={this.props.selectedCategory}
        onPressItem={this.props.onCategoryChosen}
      />
    );
  };

  render() {
    return (
      <View style={_styles.container}>
        <FlatList
          data={this.props.items.categories.edges}
          renderItem={this._renderRow}
          horizontal={true}
          keyExtractor={(item, index) => item.node.id}
          randomUpdateProp={this.state.updated}
        />
      </View>
    );
  }

}

( )

:

render() {
    const idsMatch = this.props.selectedCategory.id == this.props.item.id;
    return (
      <TouchableHighlight onPress={this._onItemPressed}>
        <View style={_styles.root}>
          <View style={[
              _styles.container,
              { backgroundColor: this._getBackgroundColor() },
            ]}>
            {idsMatch &&
              <Image
                style={_styles.icon}
                source={require('./../../res/img/asd.png')}
              />}
            {!idsMatch &&
              <Image
                style={_styles.icon}
                source={require('./../../res/img/dsa.png')}
              />}
            <Text style={_styles.text}>
              {capitalizeFirstLetter(this.props.item.name)}
            </Text>
          </View>
          <View style={_styles.bottomView}>
            <View style={_styles.greyLine} />
          </View>
        </View>
      </TouchableHighlight>
    );
  }

, , , .

:

_onCategoryChosen = category => {
    var oldReportCopy = this.state.report;
    oldReportCopy.selectedCategory = category;
    this.setState(Object.assign({}, this.state, { report: oldReportCopy }));
  };

:

state = {
    ...
    report: defaultStateReport,
  };

const defaultStateReport = {
  selectedCategory: {
    id: 'some-long-od',
    name: '',
  },
  ...
};

+16
3

,


_onCategoryChosen = category => {
    var oldReportCopy = this.state.report; // This does not create a copy!
    oldReportCopy.selectedCategory = category;
    this.setState(Object.assign({}, this.state, { report: oldReportCopy }));
};

_onCategoryChosen = category => {
    var oldReportCopy = Object.assign({}, this.state.report);
    oldReportCopy.selectedCategory = category;
    // setState handles partial updates just fine, no need to create a copy
    this.setState({ report: oldReportCopy });
};

  1. FlatList , _renderRow selectedCategory, ( ), FlatList . , extraData prop.

    <FlatList
      data={this.props.items.categories.edges}
      renderItem={this._renderRow}
      horizontal={true}
      keyExtractor={(item, index) => item.node.id}
      extraData={this.props.selectedCategory}
    />
    
+40

, extraData :

  <FlatList
    data={this.props.data}
    extraData={this.props}
    keyExtractor={this._keyExtractor}
    renderItem={this._renderItem}
  />
+11

I agree with Nimelrian. Also, if your state is Array, you can create an Array Object from this state by doing:

 var oldReportCopy = Object.assign([], this.state.report);

Then use the .push () method to add a new object to it, for example:

oldReportCopy.push(selectedCategory);

Then you can return this new Array object to state:

this.setState({ report: oldReportCopy });
0
source

Source: https://habr.com/ru/post/1678231/


All Articles