【问题标题】:Fetching JSON and iterating through the values in react-native获取 JSON 并遍历 react-native 中的值
【发布时间】:2017-08-22 21:40:09
【问题描述】:

我是本机反应新手,我试图简单地遍历一个示例 json 文件,但收到错误 undefined is not a function (evalating 'this.state.results.map')

我最初将状态设置为一个对象,所以不知道为什么我会收到这个错误。

这里是 JS

import React, { Component } from 'react';
import { AppRegistry, ListView, Text, View, StyleSheet, TouchableHighlight } from 'react-native';

var REQUEST_URL = 'https://facebook.github.io/react-native/movies.json';

class WPReact extends Component {
  constructor(props) {
    super(props);
    this.state = {results: []};
  }
  componentDidMount() {
    this.fetchData();
  }
  fetchData() {
    fetch(REQUEST_URL)
      .then((response) => response.json())
      .then((responseData) => {
        this.setState({
          results : { responseData }
        });
      })
      .done();
  }
  render() {
    return this.renderJSON();
  }
  renderJSON() {
    contents = this.state.results.map((item) => {
      <View key={item.movies.title} style={ styles.container }>
        <Text style={styles.title}>
          {item.movies.title}
        </Text>
      </View>
     });
    return (
      <View style={styles.container}>
        {contents}
      </View>
    );
  }
}

var Dimensions = require('Dimensions');

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#FFFFFF',
  },
  textContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  title: {
    fontSize: 30,
    textAlign: 'center',
    margin: 10,
  },
  text: {
    fontSize: 18,
    paddingLeft: 20,
    paddingRight: 20,
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

// App registration and rendering
AppRegistry.registerComponent('AwesomeProject', () => WPReact);

编辑

所以我已经编辑了 renderJSON() 并删除了你所说的 responseData 的大括号,因为它已经是一个对象:

renderJSON() {

    console.log(this.state.results.description);
    contents = this.state.results.movies.map((item) => {
      <View key={item.title} style={ styles.container }>
        <Text style={styles.title}>
          {item.title}
        </Text>
      </View>
     });
    return (
      <View style={styles.container}>
        {contents}
      </View>
    );
  }

我添加了一个控制台日志,看看我是否可以输出一些数据,我可以看到描述。我使用的示例 JSON 是(来自 react 的演示):

{
  "title": "The Basics - Networking",
  "description": "Your app fetched this from a remote endpoint!",
  "movies": [
    { "title": "Star Wars", "releaseYear": "1977"},
    { "title": "Back to the Future", "releaseYear": "1985"},
    { "title": "The Matrix", "releaseYear": "1999"},
    { "title": "Inception", "releaseYear": "2010"},
    { "title": "Interstellar", "releaseYear": "2014"}
  ]
}

我可以记录描述和标题。但我仍然收到:ReactNativeJS: undefined is not an object (evaluating 'this.state.results.movies.map')

如果我尝试记录console.log(this.state.results.movies[0].title),我会收到undefined is not an object (evaluating 'this.state.results.movies[0]')

fetchData() {
    fetch(REQUEST_URL)
      .then((response) => response.json())
      .then((responseData) => {
        console.log(responseData);
        this.setState({
          results : responseData
        });
      })
      .done();
  }

console.log(responseData) 显示:

03-29 13:49:53.028  3062  4143 I ReactNativeJS: { title: 'The Basics - Networking',
03-29 13:49:53.028  3062  4143 I ReactNativeJS:   description: 'Your app fetched this from a remote endpoint!',
03-29 13:49:53.028  3062  4143 I ReactNativeJS:   movies: 
03-29 13:49:53.028  3062  4143 I ReactNativeJS:    [ { title: 'Star Wars', releaseYear: '1977' },
03-29 13:49:53.028  3062  4143 I ReactNativeJS:      { title: 'Back to the Future', releaseYear: '1985' },
03-29 13:49:53.028  3062  4143 I ReactNativeJS:      { title: 'The Matrix', releaseYear: '1999' },
03-29 13:49:53.028  3062  4143 I ReactNativeJS:      { title: 'Inception', releaseYear: '2010' },
03-29 13:49:53.028  3062  4143 I ReactNativeJS:      { title: 'Interstellar', releaseYear: '2014' } ] }

console.log(this.state.results.movi​​es);

03-29 14:18:05.483  3062  4726 I ReactNativeJS: undefined
03-29 14:18:05.510  3062  4726 I ReactNativeJS: [ { title: 'Star Wars', releaseYear: '1977' },
03-29 14:18:05.510  3062  4726 I ReactNativeJS:   { title: 'Back to the Future', releaseYear: '1985' },
03-29 14:18:05.510  3062  4726 I ReactNativeJS:   { title: 'The Matrix', releaseYear: '1999' },
03-29 14:18:05.510  3062  4726 I ReactNativeJS:   { title: 'Inception', releaseYear: '2010' },
03-29 14:18:05.510  3062  4726 I ReactNativeJS:   { title: 'Interstellar', releaseYear: '2014' } ]

【问题讨论】:

  • 当你console.log(this.state.results.movies)时会发生什么?
  • 我已经修改了我原来的帖子给你看,不知道为什么那里有一个未定义的?
  • 即使在您使用 JSON.parse 之后也会发生这种情况,正如我在修改后的答案中所建议的那样?
  • 啊哈,您在将结果设置为状态之前正在记录它们!在您的 render 方法中调用 this.renderJSON 之前记录它们
  • @Pineda 将console.log(this.state.results.movies) 放在渲染方法中输出与我发布的上述内容相同,但仍显示未定义。

标签: javascript reactjs react-native


【解决方案1】:

我发现你需要改变一些事情。

首先,当你使用 ES6 在构造函数中做这个this.fetchData = this.fetchData.bind(this); 时,你需要绑定 fetchData 方法(寻找其他方法来做到这一点)。

其次,map 应该应用于 this.state.results.movies,因为这是数组(在您的帖子之后)。 this.state.results 不是数组,是包含数组的对象。

import React, { Component } from 'react';
import { AppRegistry, ListView, Text, View, StyleSheet, TouchableHighlight } from 'react-native';

var REQUEST_URL = 'https://facebook.github.io/react-native/movies.json';

class WPReact extends Component {
  constructor(props) {
    super(props);

    this.state = {
      //Lets initialize results with the same struct we expect to receive from the api
      results: {
        title: '',
        description: '',
        movies: []
      }
    };
    //Using ES6 we need to bind methods to access 'this'
    this.fetchData = this.fetchData.bind(this);
  }

  componentDidMount() {
    this.fetchData();
  }

  fetchData() {
    fetch(REQUEST_URL)
      .then((response) => response.json())
      .then((responseData) => {
        this.setState({
          results: responseData
        });
      })
      .done();
  }

  render() {
    //this.state.results.movies is the array you have to iterate
    contents = this.state.results.movies.map((item) => {
      //We need to return the corresponding mapping for each item too.
      return (
          <View key={item.title} style={ styles.container }>
            <Text style={styles.title}>
              {item.title}
            </Text>
          </View>
        );
     });
    return (
      <View style={styles.container}>
        {contents}
      </View>
    );
  }
}

var Dimensions = require('Dimensions');

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#FFFFFF',
  },
  textContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  title: {
    fontSize: 30,
    textAlign: 'center',
    margin: 10,
  },
  text: {
    fontSize: 18,
    paddingLeft: 20,
    paddingRight: 20,
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

// App registration and rendering
AppRegistry.registerComponent('AwesomeProject', () => WPReact);

如果它有效,请告诉我,我还没有测试,但我很快就会测试。

【讨论】:

  • 获取在没有绑定的情况下工作。问题在于它返回的数据......
  • 看看我的第二点。我认为他需要迭代 results.movi​​es
  • 第二点现在没有实际意义,因为在一小时前提出了这个确切的点,所以对原始问题进行了编辑:)
  • 好吧,在构造函数中,results 被初始化为一个数组。为什么不尝试将results 一方面与movies 分开,另一方面将其余信息分开?
  • 取决于结果返回一个对象还是多个对象。在当前情况下,它返回一个单一对象,它有可能打算返回一个数组。这是 OP 需要澄清的事情
【解决方案2】:

使用 ES6 类的 React 组件不会将 this 自动绑定到非 React 方法。在您的构造函数中,添加:

this.renderJSON = this.renderJSON.bind(this)

【讨论】:

  • 如果你说的是这样的话,那this.fetch岂不是也失败了?
【解决方案3】:

responseData 必须是一个数组,Array#map() 方法才能用作其上的方法。

您正在将 results 设置为包含您的 responseData 值的对象:

this.setState({ 
  results : { responseData } // Object literal notation albeit possibly incorrect depending on the value of responseData
});

如果您确定 responseData 是一个数组,请删除周围的大括号:

this.setState({ 
  results :  JSON.parse(responseData);
  // You'll want to parse your JSON data here too :)
  // If responseData is an array, you'll be able to call .map on it
});

// this.state.results.movies.map should now work
// (given the structure of the expected JSON)

【讨论】:

  • 所以我移除了大括号,让我更进一步,但仍然收到相同的地图错误。
  • 您能否更新您的问题以显示responseData 中返回的值?可能是返回的值不是数组
  • 所以这看起来你收到了一个对象。您是期待这些对象的数组,还是尝试通过titles 属性进行映射?
  • 我已经修改了答案,在 state 上设置 results 属性时包括解析 JSON 数据
  • 当我添加时,我得到JSON Parse error: Unexpected identifier "object"
猜你喜欢
  • 2021-09-21
  • 2020-08-25
  • 2021-09-29
  • 2021-03-08
  • 2017-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多