Estoy trabajando con reactjs y parece que no puedo evitar este error al intentar mostrar datos JSON (ya sea del archivo o del servidor):
Uncaught TypeError: this.props.data.map is not a function
He mirado:
Reaccionar código arrojando "TypeError: this.props.data.map no es una función"
React.js this.props.data.map () no es una función
Ninguno de estos me ha ayudado a solucionar el problema. Después de que se cargue mi página, puedo verificar que this.data.props no está indefinido (y tiene un valor equivalente al objeto JSON - puede llamar con window.foo
), por lo que parece que no se está cargando a tiempo cuando lo llama ConversationList. ¿Cómo me aseguro de que el map
método funcione en los datos JSON y no en una 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')
);
}
})
EDITAR: agregar conversaciones de muestra.json
Nota: la llamada this.props.data.conversations
también devuelve un error:
var conversationNodes = this.props.data.conversations.map...
devuelve el siguiente error:
Error de tipo no detectado: no se puede leer la propiedad 'mapa' de indefinido
Aquí está conversations.json:
{"user_has_unread_messages":false,"unread_messages_count":0,"conversations":[{"id":18768,"last_message_snippet":"Lorem ipsum","other_user_id":10193}]}
fuente
Respuestas:
La
.map
función solo está disponible en array.Parece que
data
no está en el formato que esperabas (está {} pero esperas []).debiera ser
Compruebe qué tipo de "datos" se está configurando y asegúrese de que sea una matriz.
Código modificado con algunas recomendaciones (validación propType y clearInterval):
fuente
lo que funcionó para mí es convertir props.data en una matriz usando
data = Array.from(props.data);
entonces podría usar ladata.map()
funciónfuente
De manera más general, también puede convertir los nuevos datos en una matriz y usar algo como concat:
Este patrón se utiliza en realidad en la aplicación de demostración ToDo de Facebook (consulte la sección "Una aplicación") en https://facebook.github.io/react/ .
fuente
No necesitas una matriz para hacerlo.
fuente
Sucede porque el componente se procesa antes de que lleguen los datos asíncronos, debe controlar antes de procesar.
Lo resolví de esta manera:
this.props && this.props.partners.length > 0 ?
fuente
Necesita convertir el objeto en una matriz para usar la
map
función:donde
this.props.location.state
está el objeto pasado a otro componente.fuente
prueba el
componentDidMount()
ciclo de vida al recuperar datosfuente