React JS - 未捕获的 TypeError: this.props.data.map 不是一个函数
React JS - 未捕获的 TypeError: this.props.data.map 不是一个函数
我正在使用Reactjs,并且在尝试显示JSON数据(无论是从文件还是服务器)时似乎无法防止出现此错误:
Uncaught TypeError: this.props.data.map is not a function
我已经看过如下内容:
React code throwing “TypeError: this.props.data.map is not a function”
React.js this.props.data.map() is not a function
这些都没有帮助我解决问题。在页面加载后,我可以验证this.data.props
不是未定义的,并且具有等效于JSON对象的值-可以使用window.foo
调用,因此当ConversationList调用它时,似乎它没有及时加载。如何确保map
方法在JSON数据上工作而不是在未定义变量上工作?
var converter = new Showdown.converter(); var Conversation = React.createClass({ render: function() { var rawMarkup = converter.makeHtml(this.props.children.toString()); return (
{this.props.id} {this.props.last_message_snippet} {this.props.other_user_id}
); } }); var ConversationList = React.createClass({ render: function() { window.foo = this.props.data; var conversationNodes = this.props.data.map(function(conversation, index) { return ( last_message_snippet={conversation.last_message_snippet} other_user_id={conversation.other_user_id} ); }); return ( {conversationNodes} ); } }); 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 (
Conversations
); } }); $(document).on("page:change", function() { var $content = $("#content"); if ($content.length > 0) { React.render( , document.getElementById('content') ); } })
编辑:添加示例conversations.json
注意-调用this.props.data.conversations
也会返回错误:
var conversationNodes = this.props.data.conversations.map...
返回以下错误:
Uncaught TypeError:无法读取未定义的map属性
这里是conversations.json:
{"user_has_unread_messages":false,"unread_messages_count":0,"conversations":[{"id":18768,"last_message_snippet":"Lorem ipsum","other_user_id":10193}]}
.map
函数仅适用于数组。
看起来data
的格式与您期望的格式不同(它是 {},但您期望的是[])。
this.setState({data: data});
应该是
this.setState({data: data.conversations});
检查"data"设置为什么类型,并确保其是一个数组。
修改的代码还有一些建议(propType验证和clearInterval):
var converter = new Showdown.converter(); var Conversation = React.createClass({ render: function() { var rawMarkup = converter.makeHtml(this.props.children.toString()); return ({this.props.id} {this.props.last_message_snippet} {this.props.other_user_id}
); } }); var ConversationList = React.createClass({ // Make sure this.props.data is an array propTypes: { data: React.PropTypes.array.isRequired }, render: function() { window.foo = this.props.data; var conversationNodes = this.props.data.map(function(conversation, index) { return (last_message_snippet={conversation.last_message_snippet} other_user_id={conversation.other_user_id} ); }); return ( {conversationNodes} ); } }); var ConversationBox = React.createClass({ loadConversationsFromServer: function() { return $.ajax({ url: this.props.url, dataType: 'json', success: function(data) { this.setState({data: data.conversations}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, getInitialState: function() { return {data: []}; }, /* Taken from https://facebook.github.io/react/docs/reusable-components.html#mixins clears all intervals after component is unmounted */ componentWillMount: function() { this.intervals = []; }, setInterval: function() { this.intervals.push(setInterval.apply(null, arguments)); }, componentWillUnmount: function() { this.intervals.map(clearInterval); }, componentDidMount: function() { this.loadConversationsFromServer(); this.setInterval(this.loadConversationsFromServer, this.props.pollInterval); }, render: function() { return (Conversations
); } }); $(document).on("page:change", function() { var $content = $("#content"); if ($content.length > 0) { React.render( , document.getElementById('content') ); } })