Je travaille avec reactjs et je ne parviens pas à empêcher cette erreur lorsque je tente d'afficher des données JSON (à partir d'un fichier ou d'un serveur):
Uncaught TypeError: this.props.data.map is not a function
J'ai regardé:
Code de réaction lançant "TypeError: this.props.data.map n'est pas une fonction"
React.js this.props.data.map () n'est pas une fonction
Aucun de ces éléments ne m'a aidé à résoudre le problème. Après le chargement de ma page, je peux vérifier que this.data.props n'est pas indéfini (et a une valeur équivalente à l'objet JSON - peut appeler avec window.foo
), il semble donc qu'il ne se charge pas à temps lorsqu'il est appelé par ConversationList. Comment m'assurer que la map
méthode fonctionne sur les données JSON et non sur une undefined
variable?
var converter = new Showdown.converter();
var Conversation = React.createClass({
render: function() {
var rawMarkup = converter.makeHtml(this.props.children.toString());
return (
<div className="conversation panel panel-default">
<div className="panel-heading">
<h3 className="panel-title">
{this.props.id}
{this.props.last_message_snippet}
{this.props.other_user_id}
</h3>
</div>
<div className="panel-body">
<span dangerouslySetInnerHTML={{__html: rawMarkup}} />
</div>
</div>
);
}
});
var ConversationList = React.createClass({
render: function() {
window.foo = this.props.data;
var conversationNodes = this.props.data.map(function(conversation, index) {
return (
<Conversation id={conversation.id} key={index}>
last_message_snippet={conversation.last_message_snippet}
other_user_id={conversation.other_user_id}
</Conversation>
);
});
return (
<div className="conversationList">
{conversationNodes}
</div>
);
}
});
var ConversationBox = React.createClass({
loadConversationsFromServer: function() {
return $.ajax({
url: this.props.url,
dataType: 'json',
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
this.loadConversationsFromServer();
setInterval(this.loadConversationsFromServer, this.props.pollInterval);
},
render: function() {
return (
<div className="conversationBox">
<h1>Conversations</h1>
<ConversationList data={this.state.data} />
</div>
);
}
});
$(document).on("page:change", function() {
var $content = $("#content");
if ($content.length > 0) {
React.render(
<ConversationBox url="/conversations.json" pollInterval={20000} />,
document.getElementById('content')
);
}
})
EDIT: ajout d'exemples de conversations.json
Remarque - l'appel this.props.data.conversations
renvoie également une erreur:
var conversationNodes = this.props.data.conversations.map...
renvoie l'erreur suivante:
Uncaught TypeError: impossible de lire la propriété 'map' d'undefined
Voici conversations.json:
{"user_has_unread_messages":false,"unread_messages_count":0,"conversations":[{"id":18768,"last_message_snippet":"Lorem ipsum","other_user_id":10193}]}
la source
Réponses:
La
.map
fonction n'est disponible que sur la baie.Il semble qu'il
data
ne soit pas dans le format que vous attendez (il est {} mais vous attendez []).devrait être
Vérifiez sur quel type "données" est défini et assurez-vous qu'il s'agit d'un tableau.
Code modifié avec quelques recommandations (validation propType et clearInterval):
la source
ce qui a fonctionné pour moi est de convertir les données props.data en un tableau en utilisant
data = Array.from(props.data);
alors je pourrais utiliser ladata.map()
fonctionla source
Plus généralement, vous pouvez également convertir les nouvelles données en un tableau et utiliser quelque chose comme concat:
Ce modèle est en fait utilisé dans l'application de démonstration ToDo de Facebook (voir la section «Une application») sur https://facebook.github.io/react/ .
la source
Vous n'avez pas besoin d'un tableau pour le faire.
la source
Cela se produit parce que le composant est rendu avant l'arrivée des données asynchrones, vous devez contrôler avant le rendu.
Je l'ai résolu de cette manière:
this.props && this.props.partners.length > 0 ?
la source
Vous devez convertir l'objet en tableau pour utiliser la
map
fonction:où
this.props.location.state
est l'objet passé dans un autre composant.la source
essayez le
componentDidMount()
cycle de vie lors de la récupération des donnéesla source