Grunch
Grunch

Reputation: 99

React native flatlist, not expected behavior

Hi I am starting to use FlatList component instead of ListView and I am having some problems trying to render the separator, I made a multiple-choice component and it is working ok but I don't understand why it is not rendering the separator from the flatlist, if I put the separator inside the renderItem function it's working ok, but I want to use it from the flatlist as a prop.

One curious thing is if I delete the itemSeparatorComponent prop from the FlatList in render method the component stops updating the checkmark (renderIndicator()) that indicates that item is selected, so it's really annoying this, I put the whole code, please check it.

React native: 0.44.0

import React, { Component } from 'react';
import { Button, Icon, Divider } from 'react-native-elements';
import { FlatList, View, TouchableOpacity, Text } from 'react-native';
import { Card, CardSection } from './commons';
import { appMainColor } from '../constants';

export default class ListOrderItems extends Component {
  static navigationOptions = {
    title: 'Realice su selección'
  };

  state = { selected: [], items: this.props.navigation.state.params.items };

  onItemPress = (item) => {
    const selected = this.state.selected;
    const index = selected.indexOf(item.name);

    if (index === -1) {
      selected.push(item.name);
    } else {
      selected.splice(index, 1);
    }

    this.setState({ selected });
  };

  isSelected = (item) => {
    return this.state.selected.indexOf(item.name) !== -1;
  };

  keyExtractor = (item, index) => {
    return index;
  };

  renderOkButton = () => {
    if (this.props.navigation.state.params.type === 'multipleChoice') {
      return (
        <Button
          raised
          borderRadius={5}
          backgroundColor={appMainColor}
          title='Aceptar'
          onPress={() => this.props.navigation.goBack()}
        />
      );
    }
  };

  renderCancelButton = () => {
    return (
      <Button
        raised
        borderRadius={5}
        backgroundColor={appMainColor}
        title='Cancelar'
        onPress={() => this.props.navigation.goBack()}
      />
    );
  };

  renderIndicator = (item) => {
    if (this.isSelected(item)) {
      return <Icon name="check-circle" color={appMainColor} />;
    }
  };

  renderSeparator = () => {
    return <Divider />;
  };

  renderItem = ({ item, index }) => {
    return (
      <TouchableOpacity
        activeOpacity={0.7}
        onPress={() => this.onItemPress(item, index)}
      >
        <View style={styles.row}>
          <View style={styles.optionLabel}>
            <Text>{item.name} (${item.price})</Text>
          </View>
          <View style={styles.optionIndicator}>
            {this.renderIndicator(item, index)}
          </View>
        </View>
      </TouchableOpacity>
    );
  };

  render() {
    return (
      <View>
        <Card>
          <CardSection>
            <FlatList
              data={this.state.items}
              keyExtractor={this.keyExtractor}
              renderItem={this.renderItem}
              itemSeparatorComponent={() => this.renderSeparator()}
            />
          </CardSection>
        </Card>
        <Card>
          <CardSection style={{ justifyContent: 'space-around' }}>
            {this.renderOkButton()}
            {this.renderCancelButton()}
          </CardSection>
        </Card>
      </View>
    );
  }
}

const styles = {
  row: {
    flexDirection: 'row',
    padding: 5
  },
  optionLabel: {
      flex: 1,
  },
  optionIndicator: {
      width: 30,
      height: 30,
      justifyContent: 'center',
      alignItems: 'center'
  }
};

Upvotes: 2

Views: 2861

Answers (2)

philipheinser
philipheinser

Reputation: 311

Flatlist list items are pure components if you want to check with are selected you should set this in the data source you pass in. Otherwise, the props for the item remain the same and the component will not rerender.

For the divider can you try itemSeparatorComponent={Divider}

Upvotes: 0

Zhang Buzz
Zhang Buzz

Reputation: 11088

I think you made some typo, it should be ItemSeparatorComponent, not itemSeparatorComponent.

Upvotes: 1

Related Questions