我正在关注reactjs教程,并且在将值从一个组件的状态传递到另一个组件时,我一直遇到问题。当执行CommentList组件中的map函数时,抛出错误'无法读取属性'map'of undefined'。从CommentBox传递到CommentList时会导致prop变为undefined的原因是什么?
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment){
return (
<div>
<h1>{comment.author} </h1>
</div>
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
var CommentBox = React.createClass({
getInitialState: function(){
return {data: []};
},
getComments: function(){
$.ajax({
url: this.props.url,
dataType: 'json',
success: function(data){
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err){
console.error(url, status, err.toString());
}.bind(this)
});
},
componentWillMount: function(){
this.getComments()
},
render: function(){
return (
<div className="commentBox">
{/*this.state.data.comments*/}
{<CommentList data={this.state.data.comments}/>}
</div>
);
}
});
React.renderComponent(
<CommentBox url="comments.json" />,
document.getElementById('content')
);
答案 0 :(得分:35)
首先,设置更安全的初始数据:
getInitialState : function() {
return {data: {comments:[]}};
},
确保您的ajax数据。
如果您遵循上述两条说明,例如Demo.
,它应该可以使用更新:你可以用条件语句包装.map块。
if (this.props.data) {
var commentNodes = this.props.data.map(function (comment){
return (
<div>
<h1>{comment.author}</h1>
</div>
);
});
}
答案 1 :(得分:11)
我想你忘了改变
data={this.props.data}
到
data={this.state.data}
在CommentBox的render函数中。在我学习本教程时,我犯了同样的错误。因此整个渲染功能应该看起来像
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm />
</div>
);
}
而不是
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.props.data} />
<CommentForm />
</div>
);
答案 2 :(得分:7)
您需要在渲染之前放置数据
应该是这样的:
var data = [
{author: "Pete Hunt", text: "This is one comment"},
{author: "Jordan Walke", text: "This is *another* comment"}
];
React.render(
<CommentBox data={data}/>,
document.getElementById('content')
);
而不是:
React.render(
<CommentBox data={data}/>,
document.getElementById('content')
);
var data = [
{author: "Pete Hunt", text: "This is one comment"},
{author: "Jordan Walke", text: "This is *another* comment"}
];
答案 3 :(得分:1)
如果"Cannot read property 'map' of undefined"
中有错误或没有props.data数组,将遇到错误"this.props.data"
。
更好的放置条件来检查数组,如
if(this.props.data){
this.props.data.map(........)
.....
}
答案 4 :(得分:0)
我考虑在taggon的答案下对这个问题发表评论,但是好吧,我觉得它对那些对细节感兴趣的人对此有更多的解释。
未捕获的TypeError:无法读取未定义的属性“值” ,严格来说是JavaScript错误。
(请注意,值可以是任何值,但此问题的值是'map')
了解这一点至关重要,这样可以避免无休止的调试周期。
此错误很常见,尤其是如果刚开始使用JavaScript(及其库/框架)。
对于React
,这与了解component lifecycle methods有很多关系。
// Follow this example to get the context
// Ignore any complexity, focus on how 'props' are passed down to children
import React, { useEffect } from 'react'
// Main component
const ShowList = () => {
// Similar to componentDidMount and componentDidUpdate
useEffect(() => {// dispatch call to fetch items, populate the redux-store})
return <div><MyItems items={movies} /></div>
}
// other component
const MyItems = props =>
<ul>
{props.items.map((item, i) => <li key={i}>item</li>)}
</ul>
/**
The above code should work fine, except for one problem.
When compiling <ShowList/>,
React-DOM renders <MyItems> before useEffect (or componentDid...) is called.
And since `items={movies}`, 'props.items' is 'undefined' at that point.
Thus the error message 'Cannot read property map of undefined'
*/
作为解决此问题的一种方法,@ taggon提供了一种解决方案(请参阅第一个anwser或链接)。
解决方案:设置一个初始值/默认值。
在我们的示例中,我们可以通过声明一个items
值来避免default
被“未定义”。空数组。
为什么??这允许React-DOM最初呈现一个空列表。
当执行useEffect
或componentDid...
方法时,该组件将使用填充的项目列表。
// Let's update our 'other' component
// destructure the `items` and initialize it as an array
const MyItems = ({items = []}) =>
<ul>
{items.map((item, i) => <li key={i}>item</li>)}
</ul>
答案 5 :(得分:0)
主要由于未找到数组而发生错误。只需检查您是否已映射到正确的数组即可。检查数组名称或声明。
答案 6 :(得分:0)
在我的情况下,当我尝试向Promise.all处理程序添加类型时会发生这种情况:
Promise.all([1,2]).then(([num1, num2]: [number, number])=> console.log('res', num1));
如果删除: [number, number]
,该错误消失了。
答案 7 :(得分:0)
这对我有用。如果我使用 props.worktyp.map,它会向我抛出地图未定义的错误。
//App.js
const worktyp = [
"Full-time",
"casual",
"part-time",
"contract"
];
function Main(props){
return(
<section>
<p>This the main body</p>
<ul style = {{textAlign:"left"}}>
**{worktyp.map((work) => <li>{work}</li>)}**
</ul>
</section>
);
}
function App() {
return (
<div className="App">
<Header name="initial"/>
**<Main work={worktyp}/>**
<Foot year ={new Date().getFullYear()}/>
</div>
);
}
//index.js
ReactDOM.render(
<App />,
document.getElementById('root')
);