ReactNative with 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(:

物品商店.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();

项目搜索屏幕.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>
);
};
}

目标是在平面列表中获取和显示 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 会触发无限的"onEndReach" => "loadNextPage((" 调用。这会导致列表无限填充(第 1、2、3 页、90、91 页(。我相信这个问题可能是由于我使用了 mobx 可观察数组和 Flatlist 是一个纯组件引起的。但是几个小时后,我似乎无法让它工作。

您可能已经尝试过此操作,但是当您输入数据时,可以尝试将可观察数组转换为数组

@observable myArray = []

data={[...myArray]}

最新更新