Je suis nouveau pour réagir en natif, et j'essaye simplement de parcourir un exemple de fichier json mais je reçois l'erreur undefined n'est pas une fonction (évaluer 'this.state.results.map')
J'ai initialement défini l'état sur un objet, donc je ne sais pas pourquoi je reçois cette erreur.
Voici le 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);
J'ai donc modifié la renderJSON () et supprimé les accolades de responseData comme vous l'avez dit, car il s'agissait déjà d'un objet:
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>
);
}
J'ai ajouté un journal de la console pour voir si je pouvais sortir une partie des données, et je peux voir la description. L’échantillon JSON que j’utilise est (démo de 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"}
]
}
Je peux enregistrer la description et le titre. Mais je reçois toujours: ReactNativeJS: undefined is not an object (evaluating 'this.state.results.movies.map')
Et si j'essaie d'enregistrer console.log(this.state.results.movies[0].title)
je reçois 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) indique:
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.movies);
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' } ]
Je vois quelques choses que vous devez changer.
Tout d'abord, vous devez lier la méthode fetchData lorsque vous utilisez ES6 en faisant ceci this.fetchData = this.fetchData.bind(this);
dans le constructeur (recherchez d'autres moyens de le faire).
Deuxièmement, map
devrait être appliqué à this.state.results.movies
car il s’agit du tableau (suivant votre message). this.state.results
n'est pas un tableau, c'est un objet contenant un tableau.
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);
Faites-moi savoir si cela fonctionne, je n'ai pas encore testé, mais je vais bientôt.
Les composants React utilisant des classes ES6 ne permettent pas à __autorienter this
de ne pas utiliser les méthodes React. Dans votre constructeur, ajoutez:
this.renderJSON = this.renderJSON.bind(this)
responseData
doit être un tableau pour que la méthode Array#map()
soit disponible en tant que méthode sur celle-ci.
Vous définissez results
sur un objet contenant la valeur de votre responseData
:
this.setState({
results : { responseData } // Object literal notation albeit possibly incorrect depending on the value of responseData
});
Supprimez les accolades si vous êtes sûr que responseData
est un tableau:
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)