React Native: ListView re-displays only selected item, not everything

I have a ListView

Modal inside that displays data. When the user clicks on an item in this list, I want a checkbox to appear next to that item to represent that item. The error I am facing is that the UI does not reflect this actual selection. So when the user clicks on the element, nothing has changed, however, when the modal is reopened, the UI displays a check mark next to the previously selected element.

The fix I found for this is to re-render the force using key

in ListView

. This is fine, but if I have images in the list, they all flash because everything is being redrawn. Without setting key

, it looks like my method is renderItems

not being called after change (user choice). Leaving that key on and adding keys to each render item doesn't seem to help either. How can I get the UI I expect without forcing re-rendering? Maybe I need to switch to FlatList

in order to control the individual rendering of the list item?

Methods:

        constructor(props) {
         super(props);
         const ds = new ListView.DataSource({
           rowHasChanged: (r1, r2) => r1 !== r2,
         });
         this.state = {
           selected: this.parseSelected(props.data),
           selectedCached: null,
           dataSource: ds.cloneWithRows(props.data),
         };
        }

        componentWillReceiveProps = nextProps => {
        if (nextProps.visible) {
          const saved = this.state.selected;
          this.setState({
            selectedCached: saved,
          });
        }
      }; 

      getKey = selected => {
    switch (this.props.type) {
      case 'SHIPPING':
        return selected.code;
      case 'REASON':
        return selected;
      case 'MULTICARDS':
        return selected.account_token;
      default:
        return null;
    }
  };

  parseSelected = selected => {
    switch (this.props.type) {
      case 'SHIPPING':
      case 'REASON':
        return selected[0];
      case 'MULTICARDS':
        return selected[this.props.selectedProduct];
      default:
        return null;
    }
  };

  tempSaveSelection = selected => {
    this.setState({ selected });
  };

renderItems = item => {
    let selected;
    let body;
    let style;
    switch (this.props.type) {
      case 'SHIPPING':
        selected = this.state.selected.code === item.code;
        body = <ShipItem token={item} />;
        break;
      case 'REASON':
        selected = this.state.selected === item;
        body = <FormattedMessage id={`reason_${item}`} />;
        style = textSection;
        break;
      case 'MULTICARDS':
        selected = this.state.selected.account_token === item.account_token;
        body = <CardItem product={item} />;
        style = textSection;
        break;
      default:
        selected = false;
        body = null;
        style = null;
    }

      

Return:

const { selected, dataSource } = this.state;
const selectedKey = this.getKey(selected);

   <ListView
      key={selectedKey}
      dataSource={dataSource}
      renderRow={this.renderItems}
    />

      

+3


source to share





All Articles