React Native:ListView仅重新渲染选定的项而不是所有内容

时间:2017-08-07 16:22:26

标签: listview react-native react-native-android react-native-ios react-native-listview

我在模态中有一个 self.automaticallyAdjustsScrollViewInsets = NO; 来呈现数据。当用户单击该列表中的项目时,我希望在该项目旁边显示复选框以表示该项目已被选中。我遇到的错误是UI不反映实际选择。因此,当用户点击项目时,没有任何改变,但是当重新打开模态时,UI显示先前所选项目旁边的复选标记。

我发现的修复方法是使用ListView中的key强制重新渲染。这没关系,但是如果我在列表中有图像,它们都会闪烁,因为一切都在重新渲染。如果不设置ListView,看起来我的方法key在更改(用户选择)后不会被调用。离开该键并为每个渲染项添加键似乎也没有帮助。如何在不强制重新渲染所有内容的情况下获得我期望的UI?也许我需要切换到renderItems来控制单个列表项的渲染?

方法:

FlatList

返回:

        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;
    }

0 个答案:

没有答案