[英]Cannot read property of undefined with array.map
I have a component which displays images on click of a button. 我有一个单击按钮即可显示图像的组件。 These images when get displayed on the screen, I want to apply an onClick listener to them such that the image that I click on gets displayed on the whole screen.
这些图像显示在屏幕上时,我想对它们应用onClick侦听器,以便我单击的图像显示在整个屏幕上。
Code: 码:
class App extends React.Component{
constructor(props){
super(props);
this.state={
images:[],
pano:'',
name:'',
list:[]
}
this.loadImages=this.loadImages.bind(this);
this.loadOne=this.loadOne.bind(this);
}
loadImages(){
console.log("load");
var that=this;
$.ajax({
type:'GET',
url:'https://demo0813639.mockable.io/getPanos',
success:function(result){
var images=that.state.images;
for(var i=0;i<result.length;i++){
that.state.images.push({"pano":result[i].pano,"name":result[i].name});
}
that.setState({
images:images
})
}
})
}
loadOne(url){
console.log("hi")
}
render(){
var list=this.state.list;
list=this.state.images.map(function(result){
//console.log(result.name);
return(<div className="box">
<div className="label">{result.name}</div>
<img src={result.pano} className="image"/>
</div>
)
})
return(
<div>
<button onClick={this.loadImages}>Click</button>
<div onClick={this.loadOne(this,this.props.result.pano)}>{list}</div>
</div>
);
}
}
loadOne()
is the function which gets called after clicking on an image. loadOne()
是单击图像后调用的函数。 I get the error: 我得到错误:
cannot read property pano of undefined
无法读取未定义的属性全景
And if I do like this: 如果我这样做:
render(){
var list=this.state.list;
list=this.state.images.map(function(result){
return(<div className="box">
<div className="label">{result.name}</div>
<img src={result.pano} className="image" onClick={this.loadOne(this,this.props.result.pano)}/>
</div>
)
})
return(
<div>
<button onClick={this.loadImages}>Click</button>
<div >{list}</div>
</div>
);
}
then I get the error: 然后我得到错误:
cannot read property loadOne of undefined.
无法读取未定义的属性loadOne。
So, how can I pass specific image url to my function? 那么,如何将特定的图像URL传递给函数?
Issue with second snippet is: 第二个片段的问题是:
1- You forgot to bind the map callback method, use arrow function : 1-您忘了绑定地图回调方法,使用箭头功能 :
var list = this.state.list;
list = this.state.images.map((result) => { //here
.....
2- You missed the bind
word here: 2-您错过了这里的
bind
词:
onClick = {this.loadOne.bind(this,result.pano)}
3- Instead of this.props.result.pano
it should be result.pano
. 3-相反的
this.props.result.pano
应该result.pano
。
Full code: 完整代码:
var list = this.state.list;
list = this.state.images.map((result) => {
return(
<div className="box">
<div className="label">{result.name}</div>
<img src={result.pano} className="image" onClick={this.loadOne.bind(this,result.pano)}/>
</div>
)
})
Working Code: 工作代码:
class App extends React.Component{ constructor(props){ super(props); this.state={ images:[], pano:'', name:'', list:[] } this.loadImages=this.loadImages.bind(this); this.loadOne=this.loadOne.bind(this); } loadImages(){ var that=this; $.ajax({ type:'GET', url:'https://demo0813639.mockable.io/getPanos', success:function(result){ var images=that.state.images; for(var i=0;i<result.length;i++){ that.state.images.push({"pano":result[i].pano,"name":result[i].name}); } that.setState({ images:images }) } }) } loadOne(pano){ console.log('pano', pano); } render(){ var list = this.state.list; list = this.state.images.map((result)=>{ return( <div className="box"> <div className="label">{result.name}</div> <img src={result.pano} className="image" onClick={this.loadOne.bind(this,result.pano)}/> </div> ) }) return( <div> <button onClick={this.loadImages}>Click</button> <div >{list}</div> </div> ); } } ReactDOM.render(<App/>,document.getElementById('container'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id='container'/>
Check this answer: Why is JavaScript bind() necessary? 检查以下答案: 为什么需要JavaScript bind()?
You need to bind you click function to that image. 您需要将单击功能绑定到该图像。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
images: [],
pano: '',
name: '',
list: []
}
this.loadImages = this.loadImages.bind(this);
//The loadOne cant be bound to this here, it needs a
//bind for each image. Effectivly creating one version of loadOne per image.
}
loadImages() {
$.ajax({
type: 'GET',
url: 'https://demo0813639.mockable.io/getPanos',
success:(result) => {
var images = this.state.images;
for (var i = 0; i < result.length; i++) {
this.state.images.push({ url: result[i].pano, name: result[i].name });
}
this.setState({
images: images
})
}
})
}
loadOne(url, mouseEvent) {
console.log(url);
}
render() {
//This can get extracted to a custom component
var imagesList = this.state.images.map((image, i) => {
return (<div key={i} className="box" >
<div className="label">{image.name}</div>
{/*This is where the bind/curry should be */}
<img onClick={this.loadOne.bind(this, image.url)} src={image.url} className="image" />
</div>
)
});
return (
<div>
<button onClick={this.loadImages}>Click</button>
<div>{imagesList}</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('container'));
Your clickhandler (loadOne) will then be called with the result.pano and the event as second argument passed in by react. 然后,您的clickhandler(loadOne)将以result.pano和事件作为第二个参数由react传入。
http://jsbin.com/zokugitopa/1/edit?js,output http://jsbin.com/zokugitopa/1/edit?js,输出
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.