我正在尝试学习如何使用react-native,所以我建立了一个小应用程序,从服务器获取用户列表,将其显示在一个listview按钮中,打开一个显示用户数据的屏幕.
我设置了一个导航器,从一个屏幕到另一个屏幕.按下行时,我可以打开一个新屏幕,但我无法想象如何将数据传递到这个新屏幕.
我在里面设置了一个导航仪 index.android.js
import React from 'react';
import {
AppRegistry,
Navigator,
} from 'react-native';
import ContactList from './src/containers/ContactList.js';
function MyIndex() {
return (
<Navigator
initialRoute={{ name: 'index', component: ContactList }}
renderScene={(route, navigator) => {
if (route.component) {
return React.createElement(route.component, { navigator });
}
return undefined;
}}
/>
);
}
AppRegistry.registerComponent('reactest', () => MyIndex);
Run Code Online (Sandbox Code Playgroud)
首先,我显示一个带有按钮和空列表视图的屏幕(ContactList.js),按下按钮后,我获取了一些用于更新的JSON数据listview:
import React, { Component, PropTypes } from 'react';
import {
Text,
View,
TouchableOpacity,
TouchableHighlight,
ListView,
Image,
} from 'react-native';
import styles …Run Code Online (Sandbox Code Playgroud) 我有一个带有3个标签的模态.每个选项卡都有一个列表视图,任何大于10行的数据集都无法正常工作.发生的是初始加载它正确显示.但是当显示更多行时,它们都是空的.不确定发生了什么.使用最新的React-Native.如果它有帮助,这里有几个截图.
<View style={{flex:1, height: this.state.visibleHeight - 100, width: this.state.visibleWidth }}>
{
(this.state.isSubdivisions) ? <Subdivisions model={this.props.model.subdivisions}/>
: (this.state.isProspects) ? <LandProspects model={this.props.model.landProspects}/>
: (this.state.isFavorites) ? <Favorites model={this.props.model.favorites}/>
: null}
</View>
Run Code Online (Sandbox Code Playgroud)
标签
class ListLandProspects extends Component {
constructor(props) {
super(props);
const foo = this.props.model.slice(0,10)
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
this.state = {
dataSource: ds.cloneWithRows(foo),
deviceHeight: Dimensions.get('window').height,
deviceWidth: Dimensions.get('window').width
}
}
componentDidUpdate(prevProps) {
if (this.props.model != prevProps.model)
this._updateLandProspects()
}
_updateLandProspects(){
const clone = this.props.model.slice()
this.setState({
dataSource: this.state.dataSource.cloneWithRows(clone)
}) …Run Code Online (Sandbox Code Playgroud) ReactNative的ListView在数据更新方面有点奇怪.
我有一个对象数组(名称:Item),它有3个属性:
项目数组显示在ListView中.每行显示项目的名称和表示启用状态的复选标记(红色表示真,灰色表示假).在我的例子中,它被简化为一个简单的字符串"true"/"false".
每行都嵌入一个带有onPress-EventHandler的TouchableOpacity,它可以切换所表示项目的启用状态.
不幸的是,ListView不会更新该行.
在调试rowHasChanged-Event时,事实证明rowHasChanged-Event永远无法确定已更改的状态,因为在切换enabled-property之后两行都已获得新状态而不对UI进行任何更新.
export default class Item {
constructor(id, name, enabled) {
this._id = id;
this._name = name;
this._enabled = enabled;
}
get id() {return this._id}
get name() {return this._name}
set name(value) {this._name = value}
get enabled() {return this._enabled}
set enabled(value) {this._enabled = value}
}
Run Code Online (Sandbox Code Playgroud)
'use strict';
import React, {PropTypes, Component} from 'react';
import {View,TouchableOpacity, TouchableHighlight,
Text, ListView, StyleSheet} from 'react-native';
import Item from './Item';
class ItemListView extends Component {
constructor(props) …Run Code Online (Sandbox Code Playgroud) 我 1 个月前开始使用 react native。现在我开始构建一个简单的从互联网获取数据并显示如下图所示的布局。
将这些结果放入网格的最佳方法是什么?
这是我的简单代码
render() {
<FlatList
data={newsData}
renderItem={
({item,index}) =>
index === 0 ? this._renderHighlightedVideo(item.node,index) :
index === 5 ? this._renderAdvertisment() :
index > 10 && (index+2) % 7 === 0 ? this._renderAdvertisment() : this._renderGridVideo(item.node, index)
}
keyExtractor={(item, index) => index}
/>
}
_renderHighlightedVideo(news, index) { }
_renderAdvertisment(){ }
_renderGridVideo(item.node, index){ }
Run Code Online (Sandbox Code Playgroud) 我使用django作为后端,并为应用程序做出反应原生.当应用程序在react-native app中打开时componentDidMount(),该方法将通过url请求django服务器:
export default class App extends React.Component {
constructor(props) {
super(props)
}
componentDidMount() {
this.fromServer()
}
fromServer() {
var headers = new Headers();
headers.append('Accept', 'application/json');
let a = fetch('http://xxx.xxx.xx.xx:8080/posts/', headers)
.then(function(response) {
console.log('fetched...')
if (response.status !== 200) {
console.log('There was a problem. Status Code: ' + response.status);
return;
}
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
}
render() {
return (
<View>
<ListView dataSource=?????></ListView>
</View>
);
}
}
Run Code Online (Sandbox Code Playgroud)
服务器将响应一组json对象.像这样:
[
{ …Run Code Online (Sandbox Code Playgroud) javascript django react-native react-native-listview react-native-android
我有一个获取初始DataSource的ListView.然后,用户可以运行搜索,该搜索将使用新的DataSource更新ListView.不幸的是,当发生这种情况时,滚动位置会重置,这并不理想.
我尝试重用相同的ListView.DataSource对象而不是创建一个新对象,但这给了我相同的结果:
...
dataSource: new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
}),
componentWillReceiveProps(nextProps) {
this.setState({
dataSource: this.dataSource.cloneWithRowsAndSections({...});
}
...
Run Code Online (Sandbox Code Playgroud)
我在dataSource更改后尝试在ListView上使用scrollTo,但是这会让应用程序跳转很多......不是很好的体验.是否有ListView设置或更新数据源的不同方法,以防止滚动位置重置?
ListView有2个粘性标题,顶部标题有2行页面描述和一个渲染3图像网格的redux容器.第二部分是最多50个组件的列表,这些组件的渲染有点重:正方形图像,一些文本和一些SVG.我当前的方法使用onContentSizeChange强制滚动位置,但这会导致滚动位置跳跃,它看起来很业余.
更新:深入研究ListView的文档和源代码,最终只需渲染ScrollView.我可以使用contentOffset来设置初始滚动位置,但是当ListView DataSource更新时它似乎没有帮助; 甚至硬编码contentOffset也无济于事.我也尝试将scrollEnabled设置为false,这确实阻止了用户驱动的滚动,但是当它的DataSource更新时,ListView滚动位置仍然被重置:s
更新2:我做了一些进一步的调试,发现建议的rowHasChange和sectionHeaderHasChanged函数只能很好地渲染需要渲染的行/节头.
我有一个ListView显示聊天会话列表(类似于Whatsapp/Facebook Messenger),具有以下内容rowHasChanged:
rowHasChanged: (r1, r2) => r1.id !== r2.id
Run Code Online (Sandbox Code Playgroud)
我注意到即使我使用了未更新的项目也会重新渲染shouldComponentUpdate.
经过一些跟踪后,我发现因为我在克隆dataSource之前对项目进行了不同的排序(新消息使项目跳转到列表的顶部),rowHasChanged正在比较不同的行.这样做是有道理的.
但它是不是有一个解决方案来支持以高效的方式进行排序?在WPF中CollectionViewSource,由于相同的问题(也支持过滤和其他),我们收到的东西除了它的数据之外还要收集.
有谁知道摆脱这些多余渲染的方法?
在Android 4.4上,ListView分隔线的厚度不一致,有些则不渲染.我无法看到这是一个代码问题,这就是我渲染它们的方式:
separator: {
height: 1,
backgroundColor: 'grey',
}
...
<ListView
renderSeparator={(sectionID, rowID) =>
<View key={`${sectionID}-${rowID}`} style={styles.separator} />
}
.../>
Run Code Online (Sandbox Code Playgroud)
以下是带有此问题的View的屏幕截图:
在iOS或Android 6上不会发生此问题.
以前有人有这个问题吗?
更新
我做了一个测试,这不是Android4的问题.在Nexus One设备上运行时,它会在所有API版本上发生(在android模拟器中)
所以我们想要的是:
在iOS中,我们可以为每个单元格类型使用多个cellIdentifier来创建高性能列表视图.
我现在拥有的是什么
render() {
const dataBlob = [
{ type: "address", data: { address, gotoEditAddress } },
{ type: "deliveryTime", data: {...} },
{ type: "cartSummary", data: {...} },
...[items.map(item => {{ type: "item", data: {...} }})],
{ type: "paymentInformation", data: {...} },
{ type: "paymentBreakdown", data: {...} },
{ type: "promoCode", data: {...} },
];
this._dataSource = this._dataSource.cloneWithRows(dataBlob);
return (
<ListView ref="ScrollView"
renderRow={this._renderRow}
dataSource={this._dataSource} />
);
)
Run Code Online (Sandbox Code Playgroud)
并在renderRow方法上
_renderRow = (rowData) => {
const { type, data …Run Code Online (Sandbox Code Playgroud) 我state用来存储以下数据。
state = {
refresh: true,
isFetching: true,
showLoadingBottom: false,
data: []
};
Run Code Online (Sandbox Code Playgroud)
在componentDidMount我手动调用一个_fetchData将数据加载到this.state.data.
当 flatlist 滚动到最后时,它会触发_fetchData两次,最终两次返回相同的数据(这是另一个问题,为什么它会触发两次?)。
一旦 flatlist 到达末尾,即没有更多数据从服务器返回,它就会进入一个无限循环,因为onEndReached即使服务器没有返回新数据并this.state.data保持不变,它也会一遍又一遍地不断触发。
这是我的render代码
render() {
return (
<View
style={{
flex: 1
}}>
<FlatList
refreshControl={
<RefreshControl
refreshing={this.state.refresh}
onRefresh={() => {
this.setState({
refresh: true
}, this._fetchData);
}}
title={"Pull To Refresh"}
tintColor={darkGrey}
titleColor={darkGrey}/>
}
onEndReachedThreshold={0.5}
onEndReached={() => {
this.setState({
showLoadingBottom: true
}, () => {
this._fetchData();
});
}}
showsVerticalScrollIndicator={false} …Run Code Online (Sandbox Code Playgroud) reactjs react-native react-native-listview react-native-android react-native-flatlist