Javascript ReactNative null不是对象(正在计算';this.state.dataSource';)
我正在Android emulator中运行以下代码,但我发现null不是对象(计算'this.state.dataSource')错误。 拜托,你能帮我看看我做错了什么吗?由于某种原因,Javascript ReactNative null不是对象(正在计算';this.state.dataSource';),javascript,reactjs,react-native,react-native-android,Javascript,Reactjs,React Native,React Native Android,我正在Android emulator中运行以下代码,但我发现null不是对象(计算'this.state.dataSource')错误。 拜托,你能帮我看看我做错了什么吗?由于某种原因,dataSource={this.state.dataSource}行变为null import React, { Component } from 'react'; import { AppRegistry, ActivityIndicator, ListView, Text, Vie
dataSource={this.state.dataSource}
行变为null
import React, {
Component
} from 'react';
import {
AppRegistry,
ActivityIndicator,
ListView,
Text,
View,
StyleSheet
} from 'react-native';
import Row from './Row';
import Header from './Header';
import SectionHeader from './SectionHeader';
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20,
},
separator: {
flex: 1,
height: StyleSheet.hairlineWidth,
backgroundColor: '#8E8E8E',
},
});
export default class NoTocarList extends Component {
constructor(props) {
super(props);
const getSectionData = (dataBlob, sectionId) => dataBlob[sectionId];
const getRowData = (dataBlob, sectionId, rowId) =>
dataBlob[`${rowId}`];
fetch('http://xxxxx.mybluemix.net/get')
.then((response) => response.json())
.then((responseJson) => {
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
getSectionData,
getRowData
});
const {
dataBlob,
sectionIds,
rowIds
} =
this.formatData(responseJson);
this.state = {
dataSource: ds.cloneWithRowsAndSections(dataBlob, sectionIds,
rowIds)
}
})
}
formatData(data) {
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
const dataBlob = {};
const sectionIds = [];
const rowIds = [];
for (let sectionId = 0; sectionId < alphabet.length; sectionId++) {
const currentChar = alphabet[sectionId];
const users = data.filter((user) =>
user.calle.toUpperCase().indexOf(currentChar) === 0);
if (users.length > 0) {
sectionIds.push(sectionId);
dataBlob[sectionId] = {
character: currentChar
};
rowIds.push([]);
for (let i = 0; i < users.length; i++) {
const rowId = `${sectionId}:${i}`;
rowIds[rowIds.length - 1].push(rowId);
dataBlob[rowId] = users[i];
}
}
}
return {
dataBlob,
sectionIds,
rowIds
};
}
render() {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ListView
style={styles.container}
dataSource={this.state.dataSource}
renderRow={(rowData) => <Row {...rowData} />}
renderSeparator={(sectionId, rowId) => <View key={rowId} />}
style={styles.separator}
renderHeader={() => <Header />}
renderSectionHeader={(sectionData) => <SectionHeader {...sectionData} />}
/>
</View>
);
}
}
AppRegistry.registerComponent('NoTocar', () => NoTocarList);
import-React{
组成部分
}从"反应",;
进口{
评估学,
活动指示器,
ListView,
文本
看法
样式表
}从“反应本机”;
从“./行”导入行;
从“./头”导入头;
从“./SectionHeader”导入SectionHeader;
const styles=StyleSheet.create({
容器:{
弹性:1,
玛金托普:20,
},
分离器:{
弹性:1,
高度:StyleSheet.hairlineWidth,
背景颜色:“#8E8E8E”,
},
});
导出默认类NOTCALLIST扩展组件{
建造师(道具){
超级(道具);
const getSectionData=(dataBlob,sectionId)=>dataBlob[sectionId];
const getRowData=(dataBlob,sectionId,rowId)=>
dataBlob[`${rowId}`];
取('http://xxxxx.mybluemix.net/get')
.then((response)=>response.json())
.然后((responseJson)=>{
const ds=new ListView.DataSource({
行已更改:(r1,r2)=>r1!==r2,
节头更改:(s1,s2)=>s1!==s2,
getSectionData,
getRowData
});
常数{
dataBlob,
节ID,
罗维德
} =
这个.formatData(responseJson);
此.state={
数据源:ds.cloneWithRowsAndSections(dataBlob,sectionid,
罗维德)
}
})
}
格式化数据(数据){
常量字母='ABCDEFGHIJKLMNOPQRSTUVWXYZ'。拆分('';
constdatablob={};
const sectionIds=[];
常量rowIds=[];
for(让sectionId=0;sectionId
user.calle.toUpperCase().indexOf(currentChar)==0;
如果(users.length>0){
sectionId.push(sectionId);
dataBlob[sectionId]={
字符:currentChar
};
rowIds.push([]);
for(设i=0;i}
style={style.separator}
renderHeader={()=>}
renderSectionHeader={(sectionData)=>}
/>
);
}
}
AppRegistry.registerComponent('NOTCAR',()=>NOTCALLIST);
问题在于,您试图在渲染后异步更新状态,但希望在第一次渲染时得到结果。另一个问题是您正在覆盖状态,而不是更新状态 构造函数中的
fetch
调用是异步的,这意味着构造函数已完成,并且在该调用解析之前已创建组件(及其状态)
constructor() {
fetch('http://xxxxx.mybluemix.net/get')
// ...
.then(() => {
// ...
// this code gets called after the component is created
// this state is also overwriting already created state
this.state = {
dataSource: ds.cloneWithRowsAndSections(dataBlob, sectionIds,
rowIds)
}
})
}
由于数据是异步获取的,因此可以在加载时添加检查并显示进度指示器(还应使用setState
而不是覆盖状态):
constructor(){
此.state={
数据源:null//显式初始化它
}
取('http://xxxxx.mybluemix.net/get')
// ...
.然后(()=>{
// ...
//使用设置状态
这是我的国家({
数据源:ds.cloneWithRowsAndSections(dataBlob,sectionid,
罗维德)
})
})
}
render(){
//在初始渲染时,状态尚未获取
//展示旋转器
如果(!this.state.dataSource){
回来
}
返回(
...
);
}
从您的示例中,您已将数据源作为null
传递到列表视图
。因此,您需要首先使用
this.state({
dataSource: {}
})
this.setState({
dataSource: ds.cloneWithRowsAndSections(dataBlob, sectionIds,
rowIds)
})
从Api
调用获得响应后,需要使用
this.state({
dataSource: {}
})
this.setState({
dataSource: ds.cloneWithRowsAndSections(dataBlob, sectionIds,
rowIds)
})
谢谢你的回答。我更新了代码,现在发现此错误null不是对象(评估'dataSource.rowIdentifies'):(不要返回状态null值使用空str“”