React.js。如何更改关键字“ this”

时间:2019-11-13 01:04:54

标签: javascript reactjs

我正在尝试从Firebase获取每个图像下载URL。似乎第一个“ this” 不同于第二个“ ”。如果我想让第二个“ this”等于第一个“ ”的值,我该怎么办?非常感谢!

getAllURL = product => {

    // Get all the images from the firebase  
    var storage = firebase.storage();
    console.log(this) // first this
    const storageRef =  storage.ref(`image/${product}`)

    storageRef.listAll().then(function(result) {         
      result.items.forEach(function(imageRef) {
            imageRef.getDownloadURL().then(function(url) {
             console.log(this) // second this is undefined
            }).catch(function(error) {});        
     })
   })   

  }





componentDidMount() {
    axios.get('/user/product')
        .then(res=>{
            if(res.data.code==0) {
                this.setState({data:res.data.data},function(){                      
                    for (var i = 0; i < this.state.data.length; i++){ 
                        this.getAllURL(this.state.data[i].productName)  
                    }                     
                 })
            }
        })
 }  

1 个答案:

答案 0 :(得分:1)

this是Javascript中最confusing features之一。我建议您进一步研究该主题。

关于快捷方式,有很多方法可以解决。

第一个方法:首先将第一个分配给某个变量。

getAllURL = product => {

    // Get all the images from the firebase  
    var storage = firebase.storage();
    console.log(this) // first this
    var firstThis = this; // some people prefered to assign "var that = this;", lol
    const storageRef =  storage.ref(`image/${product}`)

    storageRef.listAll().then(function(result) {         
        result.items.forEach(function(imageRef) {
            imageRef.getDownloadURL().then(function(url) {
                 console.log(firstThis); // use the new variable to refer to the firstThis
            }).catch(function(error) {});        
        });
    });
}

第二种方法:利用javascript中的bind函数(从功能编程的角度来看,它有点高级,而且效果更好)

getAllURL = product => {

    // Get all the images from the firebase  
    var storage = firebase.storage();
    console.log(this) // first this
    const storageRef =  storage.ref(`image/${product}`)

    storageRef.listAll().then((function(result) {         
        result.items.forEach((function(imageRef) {
            imageRef.getDownloadURL().then((function(url) {
                 console.log(this);
            }).bind(this)).catch(function(error) {}); // yet another binding to propagate "this" inside
        }).bind(this)); // another binding to force "this" on this yet another inline function to equal the first this (propagate it down)
    }).bind(this)); // this binding will force "this" inside this inline function to equals the firstThis
}

注意:如果减少内联函数的数量,可能会减少混乱

getAllURL = product => {

    // Get all the images from the firebase  
    var storage = firebase.storage();
    console.log(this) // first this
    const storageRef =  storage.ref(`image/${product}`)

    storageRef.listAll().then(listAllCallback.bind(this));
}

function listAllCallback(result) {
    for (var i = 0; i<result.items.length; i++) {
        var imageRef = result.items[i];
        imageRef.getDownloadURL()
            .then(downloadUrlCallback.bind(this))
            .catch(function(error) {});
    }
}

function downloadUrlCallback(url) {
    console.log(this); // second this
}