开发者问题收集

在渲染时获取未定义的不是React native中的对象

2015-12-27
82702

我是 ReactReact native 的新手,正在尝试 从 API 检索数据,然后渲染它,但似乎遇到了问题。

我可以从 API 中获取数据,但是当我尝试 渲染 它时,我收到了各种错误。

本质上,我所做的就是渲染从 API 返回的照片。应该很简单吧?如果有人能为我指明正确的方向,我将不胜感激。

我收到的错误如下:

undefined is not an object (evaluating 'this.props.photos') in RenderPhotos_render

我可能太早进入 React Native ...请原谅我知识的匮乏!

var AwesomeProject = React.createClass({
    getInitialState: function() {
      return {
        isLoading: true,
        photos: this.props.photos
      };
    },
    componentWillMount: function(){
      fetch("http://localhost:3000/api/photos/", {
          method: "GET", 
          headers: {
            "x-access-token":"xxxxx",
            "x-key":"xxxx"
          },
        })
        .then((response) => response.json())
        .then((responseData) => {
            AlertIOS.alert(
                "GET Response",
                "Search Query -> " + JSON.stringify(responseData)
            )
            this.setState({
              isLoading: false
            });
            this.setState({
              photos: JSON.stringify(responseData)
            });
        })
        .done();
    },
    render: function() {
        if(this.state.isLoading){
          return <View><Text>Loading...</Text></View>
       }
        return (
            <RenderPhotos photos={this.props.photos}/>
        );
    },

});

var RenderPhotos = React.createClass({
  getInitialState: function() {
      return {
        photos: this.props.photos
      };
  },
  render: function(){
    var photos = Photos;
    return (
      <View>
        <Text> {this.props.photos[0]} </Text>
      </View>
    )
  }
});
2个回答

for those who dont find solution to their problems in answers above:-

这解决了我的问题: 我将代码从

import {React} from 'react';

更改为

import React from 'react';

发生的事情是,由于 React 默认从模块导出,因此我无法用花括号将其包裹起来。

Shiva
2019-01-03

您有两个问题。

首先,您传递给 RenderPhotos 的 prop 是 this.props.photos ,它在 AwesomeProject 中未定义。查看 RenderPhotosrender() 函数,您尝试访问 this.props.photos 索引 0 处的元素,但该元素未定义。这可能是导致您出现错误的原因。我怀疑您是想在 AwesomeProject 组件的 render() 函数中将 photos prop 设置为等于 this.state.photos

其次,在 AwesomeProject 组件的 componentWillMount() 中,从 API 获取照片后,您会进行两次状态更改:

this.setState({
  isLoading: false
});

this.setState({
  photos: JSON.stringify(responseData)
});

React 可能会批量处理这两个 setState() 调用,但不能保证,因此两个状态属性将同时设置,并且 render() 方法只会被调用一次。但是,如果这些 setState() 函数同步执行,则在 this.state.loading === falsethis.state.photos === undefined 时将调用 render() 函数。 RenderPhotos 组件将挂载并接收 prop photos={this.state.photos (在进行我上面描述的更改之后)。不幸的是,由于 this.state.photos 未定义,当您尝试在 RenderPhotosrender() 函数内访问 this.props.photos[0] 时,您将遇到与上述相同的问题。以下是我解决您的问题的建议:

var AwesomeProject = React.createClass({
    getInitialState: function() {
      return {
        isLoading: true,
        photos: this.props.photos
      };
    },
    componentWillMount: function(){
      fetch("http://localhost:3000/api/photos/", {
          method: "GET", 
          headers: {
            "x-access-token":"xxxxx",
            "x-key":"xxxx"
          },
        })
        .then((response) => response.json())
        .then((responseData) => {
            AlertIOS.alert(
                "GET Response",
                "Search Query -> " + JSON.stringify(responseData)
            )
            // Set both state properties at the same time to avoid passing an undefined value as a prop to RenderPhotos
            this.setState({
              isLoading: false,
              photos: JSON.stringify(responseData)
            });
        })
        .done();
    },
    render: function() {
        if(this.state.isLoading){
          return <View><Text>Loading...</Text></View>
       }
       // RenderPhotos should receive this.state.photos as a prop, not this.props.photos
        return (
            <RenderPhotos photos={this.state.photos}/>
        );
    },

});

var RenderPhotos = React.createClass({
  getInitialState: function() {
      return {
        photos: this.props.photos
      };
  },
  render: function(){
    var photos = Photos;
    return (
      <View>
        <Text> {this.props.photos[0]} </Text>
      </View>
    )
  }
});
Brandon
2015-12-27