在回调函数中引用.this时出错

时间:2016-09-21 10:41:49

标签: javascript reactjs callback redux firebase-storage

我可以使用promises成功上传到firebase存储并检索图像URL,但我想将进度条链接到上传完成百分比。到目前为止我所取得的成就:当我从一个组件调用此函数时:

this.props.handleNewPrizeImageUpload(this.progressCallback, this.imageUploadCompletionCallback, prizeImage)

在组件中定义了这些回调:

  progressCallback (progress) {
    **//this.someOtherFunction(progress).bind(this)**
    return console.log('Upload is ' + progress + '% done')

  }

  imageUploadCompletionCallback (url) {
     **//this.props.someOtherFunctionB(url)**
    console.log('SAVEPRIZEIMAGE RAN SUCCESFULLY RETURN URL : ', url)}

此功能运行:

export function handleNewPrizeImageUpload (progressCallback, imageUploadCompletionCallback,
  prizeImage) {
  savePrizeImage(progressCallback, imageUploadCompletionCallback,prizeImage)
}

savePrizeImage是一个保存图像并相应地运行回调函数的函数。

我可以成功检索进度值和URL数据,但我遇到的问题是我无法在这些回调中使用我的其他定义函数来执行检索到的数据,我不断收到错误< strong>此未定义。我试过bind(这个)它不起作用。

错误:

  

未捕获的TypeError:无法读取属性&some; \ n30 / OtherFther&#39;的   未定义

我尝试过:

  constructor (props) {
    super(props)
    this.someOtherFunction = this.someOtherFunction.bind(this)
  }

然后像这样调用它:

  progressCallback (progress) {
    console.log('Upload is ' + progress + '% done')
    this.someOtherFunction(progress)
  }

  someOtherFunction (progress) {
    console.log('HAHAHA')
  }

Heer是整个组件代码块:

import React, { Component, PropTypes } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import {CreatePrizeForm} from 'components'
import * as ActionCreators from 'redux/modules/prizes'

export class CreatePrizeFormContainer extends Component {

  static contextTypes = {
    router: PropTypes.object.isRequired
  }

  constructor (props) {
    super(props)
    // this.someOtherFunction = this.someOtherFunction.bind(this)
    // this.progressCallback = this.progressCallback.bind(this)
  }

  handlePrizeData (prizeImage) {
    this.props.handleNewPrizeImageUpload(this.progressCallback, this.imageUploadCompletionCallback, PrizeImage)
  }


  progressCallback (progress) {
    console.log('Upload is ' + progress + '% done')
    //this.someOtherFunction(progress)
  }


  imageUploadCompletionCallback (url) {
    console.log('SAVE TO FIREBASE RAN SUCCESFULLY RETURNED IMAGE URL : ', url)
  }

  someOtherFunction (progress) {
    console.log('HAHAHA')
  }

  render () {
    return (
      <div>
        <CreatePrizeForm addPrizeData = {(prizeImage) => { this.handlePrizeData(prizeImage) }}/>
      </div>
    )
  }
}

function mapStateToProps (state, props) {
  return {
  }
}

function mapDispatchToProps (dispatch, props) {
  return bindActionCreators(ActionCreators, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(CreatePrizeFormContainer)

1 个答案:

答案 0 :(得分:0)

当您传递对函数的引用(例如作为参数或其他赋值)时,它将不会将其上下文绑定到它。

this.progressCallback参数就是这种情况:

this.props.handleNewPrizeImageUpload(this.progressCallback, ... )

那个progressCallback参数变量没有链接到this,即使你这样传递它 - 这也是造成很多误解的原因;你不是唯一一个。

按如下方式解决:

this.props.handleNewPrizeImageUpload(this.progressCallback.bind(this), ... )

在此看到非常好的Q&A

以下是一些修改为工作代码段的代码:

&#13;
&#13;
"strict"
// Dummy Component class for this snippet only
class Component { constructor (props) { this.props = props } }
// Your class:
class CreatePrizeFormContainer extends Component {
  constructor (props) { super(props) }
  handlePrizeData (prizeImage) {
    this.props.handleNewPrizeImageUpload(
        this.progressCallback.bind(this),
        this.imageUploadCompletionCallback.bind(this), prizeImage)
  }
  progressCallback (progress) {
    console.log('Upload is ' + progress + '% done')
    this.someOtherFunction(progress)
  }
  imageUploadCompletionCallback (url) {
    console.log('SAVE TO FIREBASE RAN SUCCESFULLY RETURNED IMAGE URL : ', url)
  }
  someOtherFunction (progress) { console.log('HAHAHA') }
}
// Dummy savePrizeImage function for this snippet only
function savePrizeImage(progressCallback, imageUploadCompletionCallback, ImageFile) {
  // Simulate two progress events
  setTimeout(function() { progressCallback(50) }, 0)
  setTimeout(function() { progressCallback(100) }, 500)
  setTimeout(function() { imageUploadCompletionCallback('http://example.com') }, 510)
}
// Create instance, passing simple prop literal
var obj = new CreatePrizeFormContainer({ 
  handleNewPrizeImageUpload: function(progressCallback, 
                                      imageUploadCompletionCallback, ImageFile) {
    savePrizeImage(progressCallback, imageUploadCompletionCallback, ImageFile)
  }
})
obj.handlePrizeData('dummyPrizeImage.img') // Call handlePrizeData
&#13;
&#13;
&#13;