繁体   English   中英

无法读取array.map的undefined属性

[英]Cannot read property of undefined with array.map

我有一个单击按钮即可显示图像的组件。 这些图像显示在屏幕上时,我想对它们应用onClick侦听器,以便我单击的图像显示在整个屏幕上。

码:

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()是单击图像后调用的函数。 我得到错误:

无法读取未定义的属性全景

如果我这样做:

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>
  );
}

然后我得到错误:

无法读取未定义的属性loadOne。

那么,如何将特定的图像URL传递给函数?

第二个片段的问题是:

1-您忘了绑定地图回调方法,使用箭头功能

var list = this.state.list;
list = this.state.images.map((result) => {   //here
    .....

2-您错过了这里的bind词:

onClick = {this.loadOne.bind(this,result.pano)}

3-相反的this.props.result.pano应该result.pano

完整代码:

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>
    )
})

工作代码:

 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'/> 

检查以下答案: 为什么需要JavaScript bind()?

您需要将单击功能绑定到该图像。

    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'));

然后,您的clickhandler(loadOne)将以result.pano和事件作为第二个参数由react传入。

http://jsbin.com/zokugitopa/1/edit?js,输出

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM