2017-09-02 73 views
0

首先,我想先说我是React Native和Shoutem的总noob。我不确定是否应该在我的问题中写下Shoutem或React Native,但这是我的问题。Shoutem提取数据不显示

我有两个屏幕:

  1. Screen1.js
  2. Screen2.js

屏蔽1显示从获取返回的项目列表。一旦我点击该项目,它将打开第二个屏幕,这是详细信息屏幕。

我正在将数据从screen1传递给screen2。在screen2中,我需要为不同的数据进行另一次获取调用,但它不起作用。我在两个屏幕上都做了完全相同的事情。

这里是我的屏蔽1代码:

import React, { 
    Component 
} from 'react'; 

import { 
    ActivityIndicator, 
    TouchableOpacity 
} from 'react-native'; 

import { 
    View, 
    ListView, 
    Text, 
    Image, 
    Tile, 
    Title, 
    Subtitle, 
    Overlay, 
    Screen 
} from '@shoutem/ui'; 

import { 
    NavigationBar 
} from '@shoutem/ui/navigation'; 

import { 
    navigateTo 
} from '@shoutem/core/navigation'; 

import { 
    ext 
} from '../extension'; 

import { 
    connect 
} from 'react-redux'; 

export class List extends Component { 
    constructor(props) { 
    super(props); 
    this.renderRow = this.renderRow.bind(this); 
    this.state = { 
     isLoading: true, 
     content: null, 
    } 

    } 

    componentDidMount() { 
    return fetch('https://www.cannabisreports.com/api/v1.0/strains').then((response) => response.json()).then((responseData) => { 
     this.setState({ 
     isLoading: false, 
     content: responseData 
     }); 
    }).done(); 
    } 

    renderRow(rowData) { 
    const { navigateTo } = this.props; 

    return (
     //<Text>{rowData.name}, {rowData.createdAt.datetime}</Text> 
     <TouchableOpacity onPress={() => navigateTo({ 
      screen: ext('Strain'), 
      props: { rowData } 
     })}> 
      <Image styleName="large-banner" source={{ uri: rowData.image && 
      rowData.image ? rowData.image : undefined }}> 
      <Tile> 
       <Title>{rowData.name}</Title> 
       <Subtitle>none</Subtitle> 
      </Tile> 
      </Image> 
     </TouchableOpacity> 
    ); 
    } 

    render() { 
    if (this.state.isLoading) { 
     return (
     <View style={{flex: 1, paddingTop: 20}}> 
      <ActivityIndicator /> 
     </View> 
    ); 
    } 

    return (
     <View style={{flex: 1, paddingTop: 20}}> 
     <ListView 
      data={this.state.content.data} 
      renderRow={rowData => this.renderRow(rowData)} 
     /> 
     </View> 
    ); 
    } 
} 

// connect screen to redux store 
export default connect(
    undefined, 
    { navigateTo } 
)(List); 

我传递rowData到画面2。然后我需要使用来自rowData的数据进行另一次获取调用,因为它是Screen2中API调用所需的路径参数。

所以基本上我需要在屏幕2一fetch调用是这样的:

fetch('https://mywebsite.com/'+rowData.something+'/myotherdata') 
     .then((response) => response.json()) 
     .then((responseJson) => { 
     this.setState({ 
      content: responseJson.data 
     }) 
     }) 
     .catch((error) => { 
     console.error(error); 
     }); 

这里是我的屏幕2代码:

export default class Strain extends Component { 

    constructor(props) { 
    super(props); 
    this.state = { 
     content: null, 
    } 
    } 

    componentDidMount() { 
    return fetch('https://mywebsite.com/'+rowData.something+'/myotherdata') 
     .then((response) => response.json()) 
     .then((responseJson) => { 
     this.setState({ 
      content: responseJson.data 
     }) 
     }) 
     .catch((error) => { 
     console.error(error); 
     }); 
    } 

    renderRow(dataContent) { 
    return (
     <Text>{dataContent.name}</Text> 
     // This does not work either -> <Text>{dataContent}</Text> 
    ); 
    } 

    render() { 
    const { rowData } = this.props; //This is coming from screen1.js 

    return (
     <ScrollView style = {{marginTop:-70}}> 
     <Image styleName="large-portrait" source={{ uri: rowData.image && 
     rowData.image ? rowData.image : undefined }}> 
      <Tile> 
      <Title>{rowData.name}</Title> 
      <Subtitle>{rowData.createdAt.datetime}</Subtitle> 
      </Tile> 
     </Image> 

     <Row> 
      <Text>Seed Company: {rowData.seedCompany.name}</Text> 
     </Row> 

     <Divider styleName="line" /> 

     <Row> 
      <Icon name="laptop" /> 
      <View styleName="vertical"> 
      <Subtitle>Visit webpage</Subtitle> 
      <Text>{rowData.url}</Text> 
      </View> 
      <Icon name="right-arrow" /> 
     </Row> 

     <Divider styleName="line" /> 

     <View style={{flex: 1, paddingTop: 20}}> 
      <ListView 
      data={content} 
      renderRow={dataContent => this.renderRow(dataContent)} 
      /> 
     </View> 

     <Divider styleName="line" /> 

     </ScrollView> 
    ); 
    } 
} 

我取URL返回的数据是这样的:

{ 
    data: { 
    name: "7.5833", 
    another_name: "8.6000", 
    different_name: "5.7500", 
    } 
} 

这只会返回一个数据对象,就像您在上面看到的一样。

当我运行代码,我得到这个错误: null is not an object (evaluating 'Object.keys(e[t])')

请让我知道如果你需要我提供更多的信息。

我已经尝试了很多不同的东西,似乎没有任何工作,所以我需要一些帮助。我究竟做错了什么?

+1

你知道哪些代码调用Object.keys(e [t])'?如果没有,你需要去浏览你的浏览器devtools并找出答案。此外,还不清楚问题中的render()代码如何与您的获取调用相关。实际调用'render()'的代码在哪里?在'this.setState({content_responseJson。data },function(){ //用新状态做某事 });'那是什么代码'//对新状态部分实际调用?这与问题中的其他代码有什么关系? – sideshowbarker

+0

@iamthestreets你在哪里看到这个错误?看起来像是缩小代码中的错误,所以很难说,尝试运行调试版本以获得更友好的错误。从我可以告诉你没有给你的'ListView'正确的'内容'。通过'this.state.content'或做'const {content} = this.state;'作为渲染函数的第一行。最好的做法是先解构(第二种方法),如果“内容”不可用,则呈现占位符。 – dodsky

+0

我使用Shoutem Builder来运行应用程序,因为这是我得到任何错误显示的唯一方法。 @sideshowbarker我删除了'function(){//用新状态做某事}'不需要它。我不确定你的代码调用'render()是什么意思。当屏幕加载它时调用'render()'。 – iamthestreets

回答

0

不知道为什么这个工作,但它确实。

我用一个函数来fetch我的数据,然后调用函数componentDidMount这样的:

getData() { 
    return fetch('https://mywebsite.com/myotherdata') 
     .then((response) => response.json()) 
     .then((responseJson) => { 
     this.setState({ 
      data: responseJson.data 
     }); 
     }) 
     .catch((error) => { 
     console.error(error); 
     }); 
    } 

    componentDidMount() { 
    this.getData(); 
    } 

然后从JSON响应获取值我这样做: this.state.data.name

我我有另一个问题,但我会创建另一个问题。