javascript - ReactNative 与 Mobx - Flatlist 无限请求项目
问题描述
我的 ReactNative 环境如下:
React Native Environment Info:
System:
OS: macOS 10.14
CPU: x64 Intel(R) Core(TM) i7-7567U CPU @ 3.50GHz
Memory: 37.92 MB / 16.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 8.12.0 - /usr/local/bin/node
Yarn: 1.9.4 - /usr/local/bin/yarn
npm: 6.4.1 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 11.2, macOS 10.13, tvOS 11.2, watchOS 4.2
IDEs:
Android Studio: 3.1 AI-173.4907809
Xcode: 9.2/9C40b - /usr/bin/xcodebuild
npmPackages:
react: 16.5.2 => 16.5.2
react-native: 0.57.1 => 0.57.1
npmGlobalPackages:
create-react-native-app: 1.0.0
react-native-cli: 2.0.1
react-native-git-upgrade: 0.2.7
考虑以下类(2):
ItemStore.js
import {action, computed, flow, observable} from "mobx";
class ItemStore {
currentPage = 0;
@observable loadingItems = false;
@observable currentSearch = "";
@observable items = [];
@computed get emptyListText() {
if (this.currentSearch.length === 0) {
return "Busque Ahora!"
} else if (this.loadingItems === true) {
return "Buscando..."
}
return `No encontramos ningun resultado para "${this.currentSearch}"`
}
@action search(searchQuery) {
this.currentSearch = searchQuery;
this.loadItems(searchQuery, (this.currentPage = 0))
}
@action loadNextPage() {
this.loadItems(this.currentSearch, (++this.currentPage))
}
@action loadItems = flow(function* (searchQuery, page) {
try {
this.loadingItems = true;
const searchResults = yield fetch(`http://192.168.0.88:10000/search?keywords=${searchQuery}&page=${page}`, {
method: 'GET',
header: {
Accept: 'application/json',
}
});
const data = yield searchResults.json();
if (data.length > 0) {
if (page === 0) { // brand new search, replace old items
this.items.replace(data)
} else { // loading another page
this.items.push(...data)
}
}
} catch (error) {
console.warn(error);
}
this.loadingItems = false;
});
}
export default new ItemStore();
ItemSearchScreen.js
import React from 'react'
import {Body, Container, Content, Header, Icon, Input, Item, Text} from 'native-base'
import {inject, observer} from "mobx-react";
import {FlatList} from 'react-native'
import Product from "./Product";
@inject('itemStore')
@observer
export default class ItemSearchScreen extends React.Component {
handleSearch = (e) => this.props.itemStore.search(e.nativeEvent.text);
handleLoadNextPage = () => this.props.itemStore.loadNextPage();
render() {
const items = this.props.itemStore.items.slice();
return (
<Container>
<Header searchBar rounded>
<Item>
<Icon name="ios-search"/>
<Input placeholder={"Buscar"}
onSubmitEditing={this.handleSearch}/>
</Item>
</Header>
<Content>
<FlatList
initialNumToRender={6}
ListEmptyComponent={
<Body>
<Text>{this.props.itemStore.emptyListText}</Text>
</Body>
}
data={items}
keyExtractor={(item) => item['id']}
onEndReached={this.handleLoadNextPage}
onEndReachedThreshold={0.5}
renderItem={({item}) => <Product product={item}/>}/>
</Content>
</Container>
);
};
}
目标是在 Flatlist 中获取并显示一组 json“产品”项目。
import React from 'react'
import {observer} from "mobx-react";
import {Body, Left, ListItem, Text, Thumbnail} from 'native-base'
@observer
export default class Product extends React.Component {
//should be replaced with cached app image
fallBackImage = 'https://www.wpclipart.com/office/sale_promo/new_item/new_item_light_red.png';
constructor(props) {
super(props);
}
render() {
let thumbnailImage = this.props.product['product_image_url'].length > 0 ? this.props.product['product_image_url'] : this.fallBackImage
return (
<ListItem>
<Left>
<Thumbnail square large source={{uri: thumbnailImage}}/>
<Text>${this.props.product['price']}</Text>
</Left>
<Body>
<Text>{this.props.product['name']}</Text>
</Body>
</ListItem>
);
}
}
通过搜索栏(在标题中)搜索产品时,会显示产品列表,但 Flatlist 会触发无限的 'onEndReached' => 'loadNextPage()' 调用。这会导致列表被无限填充(第 1、2、3.... 90、91... 页)。我相信这个问题可能是由于我使用 mobx 可观察数组和 Flatlist 是 PureComponent 造成的。但经过几个小时后,我似乎无法让它工作。
解决方案
您可能已经尝试过,但可以在输入数据时尝试将可观察数组转换为数组
@observable myArray = []
data={[...myArray]}
推荐阅读
- git - 如何查看将要提交的文件
- meteor - 如果不是通过 id,我如何访问 GraphQL 中的数据?
- graphql-ruby - 如何定义一个包含数组数组的类型?
- google-apps-script - 如何自定义 onEdit() 脚本以处理从剪贴板粘贴值列表时修改的所有行?
- python - 为什么我使用`sum`得到一个TypeError“'float' object is not iterable”?
- css - 如何在所有站点上仅使用 css 获取具有相同数据属性的元素?
- sql-server - 无法使用managment studio连接sql server
- c++ - 为什么 qCDebug() 宏是这样定义的?
- android - 使用 SHA256 和 CertificatePinner 在 Volley 中进行 SSL 固定
- android - 自定义 Html.TagHandler 和段落中两个内部跨度的样式