如何在ListView React-native中过滤数据? [英] How to filter data in 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);
几点:
- 您的组件是有状态的。有一个状态只属于组件:搜索术语。将其保持在组件状态。
- 不要更改生命周期功能中的数据源。这是你知道它需要的最新点:渲染。
- 我猜测
assetFetch
中有异步,所以你可能应该在componentDidMount
中返回它。 - 我从
componentWillMount
更改为componentDidMount
。建议将异步提取componentDidMount
。如果您进行服务器端渲染,这可能很重要。 - 如果没有搜索词,则跳过过滤。这只是列表非常大的问题。
- Your component is stateful. There is one piece of state that belongs only to the component: the search term. Keep that in component state.
- Don't change the data source in life cycle functions. Do it the latest point you know it's needed: in render.
- I'm guessing that there's something async in
assetFetch
, so you probably should return it incomponentDidMount
. - I changed from
componentWillMount
tocomponentDidMount
. It's recommended to put async fetchingcomponentDidMount
. This can matter if you ever do server side rendering. - 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屋!