Моя среда 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>
);
};
}
Цель состоит в том, чтобы получить и отобразить массив элементов json 'product' в Flatlist.
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.Но после многих часов я не могу заставить его работать.