如何在ListView React-native中过滤数据? [英] How to filter data in ListView React-native?

查看:70
本文介绍了如何在ListView React-native中过滤数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试过滤我的数组对象列表,然后尝试使用新的DataSource在ListView中显示。但是,列表未被过滤。我知道我的过滤功能正常工作。 (我在console.log中检查过它)

I am trying to filter my array object list and then trying to display in the ListView with new DataSource. However, the list is not getting filtered. I know that my filter function works correctly. ( I checked it in the console.log )

我正在使用Redux将我的状态映射到prop。然后尝试过滤道具。这是错误的方法吗?

I am using Redux to map my state to prop. And then trying to filter the prop. Is this the wrong way?

这是我的代码:

/*global fetch:false*/
import _ from 'lodash';
import React, { Component } from 'react';
import { ListView, Text as NText } from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import {
  Container, Header, Item,
  Icon, Input, ListItem, Text,
  Left, Right, Body, Button
} from 'native-base';


import Spinner from '../common/Spinner';
import HealthImage from '../misc/HealthImage';
import { assetsFetch } from '../../actions';

const ds = new ListView.DataSource({
  rowHasChanged: (r1, r2) => r1 !== r2
});

class AssetsList extends Component {
  componentWillMount() {
    this.props.assetsFetch();

    // Implementing the datasource for the list View
    this.createDataSource(this.props.assets);
  }

  componentWillReceiveProps(nextProps) {
    // Next props is the next set of props that this component will be rendered with.
    // this.props is still equal to the old set of props.
    this.createDataSource(nextProps.assets);
  }

  onSearchChange(text) {
    const filteredAssets = this.props.assets.filter(
      (asset) => {
        return asset.name.indexOf(text) !== -1;
      }
    );

    this.dataSource = ds.cloneWithRows(_.values(filteredAssets));
  }

  createDataSource(assets) {
    this.dataSource = ds.cloneWithRows(assets);
  }


  renderRow(asset) {
    return (
      <ListItem thumbnail>
          <Left>
              <HealthImage health={asset.health} />
          </Left>
          <Body>
              <Text>{asset.name}</Text>

              <NText style={styles.nText}>
                Location: {asset.location} |
                Serial: {asset.serial_number}
              </NText>
              <NText>
                Total Samples: {asset.total_samples}
              </NText>

          </Body>
          <Right>
              <Button transparent onPress={() => Actions.assetShow()}>
                  <Text>View</Text>
              </Button>
          </Right>
      </ListItem>
    );
  }



  render() {
    return (
     <Input
                  placeholder="Search"
                  onChangeText={this.onSearchChange.bind(this)}
                />
        <ListView
          enableEmptySections
          dataSource={this.dataSource}
          renderRow={this.renderRow}
        />


    );
  }
}

const mapStateToProps = state => {
  return {
    assets: _.values(state.assets.asset),
    spinner: state.assets.asset_spinner
  };
};

export default connect(mapStateToProps, { assetsFetch })(AssetsList);

我在这里做错了什么?

What am I doing wrong here?

推荐答案

要跟踪这里发生的事情有点困难。我会简化它是这样的:

It's a little hard to follow what's going on here. I would simplify it to be like so:

class AssetsList extends Component {
  state = {};

  componentDidMount() {
    return this.props.assetsFetch();
  }

  onSearchChange(text) {
    this.setState({
      searchTerm: text
    });
  }

  renderRow(asset) {
    return (
      <ListItem thumbnail>
          <Left>
              <HealthImage health={asset.health} />
          </Left>
          <Body>
              <Text>{asset.name}</Text>

              <NText style={styles.nText}>
                Location: {asset.location} |
                Serial: {asset.serial_number}
              </NText>
              <NText>
                Total Samples: {asset.total_samples}
              </NText>

          </Body>
          <Right>
              <Button transparent onPress={() => Actions.assetShow()}>
                  <Text>View</Text>
              </Button>
          </Right>
      </ListItem>
    );
  }

  getFilteredAssets() {

  }

  render() {
    const filteredAssets = this.state.searchTerm
      ? this.props.assets.filter(asset => {
          return asset.name.indexOf(this.state.searchTerm) > -1;
        })
      : this.props.assets;
    const dataSource = ds.cloneWithRows(filteredAssets);
    return (
     <Input
                  placeholder="Search"
                  onChangeText={this.onSearchChange.bind(this)}
                />
        <ListView
          enableEmptySections
          dataSource={dataSource}
          renderRow={this.renderRow}
        />
    );
  }
}

const mapStateToProps = state => {
  return {
    assets: _.values(state.assets.asset),
    spinner: state.assets.asset_spinner
  };
};

export default connect(mapStateToProps, { assetsFetch })(AssetsList);

几点:


  1. 您的组件是有状态的。有一个状态只属于组件:搜索术语。将其保持在组件状态。

  2. 不要更改生命周期功能中的数据源。这是你知道它需要的最新点:渲染。

  3. 我猜测 assetFetch 中有异步,所以你可能应该在 componentDidMount 中返回它。

  4. 我从 componentWillMount 更改为 componentDidMount 。建议将异步提取 componentDidMount 。如果您进行服务器端渲染,这可能很重要。

  5. 如果没有搜索词,则跳过过滤。这只是列表非常大的问题。

  1. Your component is stateful. There is one piece of state that belongs only to the component: the search term. Keep that in component state.
  2. Don't change the data source in life cycle functions. Do it the latest point you know it's needed: in render.
  3. I'm guessing that there's something async in assetFetch, so you probably should return it in componentDidMount.
  4. I changed from componentWillMount to componentDidMount. It's recommended to put async fetching componentDidMount. This can matter if you ever do server side rendering.
  5. Skip filtering if there is no search term. This would only matter if the list is very large.

我有点担心的一件事是在组件内部取模的模式,将其置于全球状态,然后依靠该组件来应对全球状态变化。因此,改变全球状态成为简单地观察某事物的副作用。我假设您正在这样做,因为 assets 在其他地方使用,这是一个方便的点,让他们从服务器清新,以便它们将显示在其他不提取的组件中他们。这种模式可能导致难以发现的错误。

One thing I have a little concern with is the pattern of fetching inside a component, putting it in global state, and then relying on that component to react to the global state change. Thus changing global state becomes a side effect of simply viewing something. I assume you are doing it because assets is used elsewhere, and this is a convenient point to freshen them from the server so that they will show up in other components that do not fetch them. This pattern can result in hard-to-find bugs.

这篇关于如何在ListView React-native中过滤数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆