1

when i try to use variable in my class function getting this error Cannot read property 'zoomInIndex' of undefined

it is working fine if i have one function, can some one help me out how to use the variable in inner function or how to bind the inner function context?

class MyContainer extends Component {

    constructor(props) {
        super(props);
        this.testClick = this.testClick.bind(this);
        this.zoomClick = this.zoomClick.bind(this);
        this.testVarible= "this is a test";
    }

    zoomClick(inout) {
    return function(e) {
         console.log(this.testVarible); // this is not working 
      }
    }
    
    
    testClick(){
       console.log(this.testVarible);
    }
    
    
}

if i use fat arrow functions it is working fine

zoomClick = inout => e => {
    console.log(this.testVarible);
}

but i don't want to use fat arrow functions in react components since i ran into a lot of issues with my webpack configuration.

so my question is how to use the variable in inner function or how to bind the inner function context with out fat arrow syntax?

1
  • You don't need to .bind zoomClick if you are not passing the function elsewhere. Only bind functions if you need to. Commented Nov 26, 2018 at 21:43

3 Answers 3

2

You need to bind the function returning from the zoomClick():

zoomClick(inout) {
    return function(e) {
        console.log(this.testVarible); // this is not working
    }.bind(this); // <-- bind(this)
}

The anonymous function which was returned had no context of this and thus it was giving the error. Because zoomClick is already bound in the constructor, you just need to bind the function(e) { ... }

Sign up to request clarification or add additional context in comments.

Comments

0

You can bind it to the class context one of two ways:

returnFunction = returnFunction.bind(this); or function() {}.bind(this).

class MyContainer extends React.Component {

    constructor(props) {
        super(props);
        this.testClick = this.testClick.bind(this);
        this.zoomClick = this.zoomClick.bind(this);
        this.testVarible = "this is a test";
    }

    zoomClick(inout) {
      let returnFunction = function(e) {
        console.log(this.testVarible);
        return this.testVarible;
      };
      returnFunction = returnFunction.bind(this);
      return returnFunction;
    }
    
    
    testClick(){
       console.log(this.testVarible);
    }
    
    render() {
      return (
        <div>{this.zoomClick(false)(false)}</div>
      );
    }
    
}

ReactDOM.render(
  <MyContainer/>,
  document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Comments

0

i don't want to use fat arrow functions in react components since i ran into a lot of issues with my webpack configuration

I'm guessing you tried to use class fields with the Babel plugin and that caused you some grief.

It's OK to use the traditional method of binding in the constructor and use arrow functions elsewhere in the code without running into those problems.

class MyContainer extends React.Component {

  constructor(props) {
    super(props);
    this.zoomClick = this.zoomClick.bind(this);
    this.testVarible = "this is a test";
  }

  zoomClick() {
    return (e) => {
      console.log(this.testVarible);
    }
  }

  render() {
    return <Button handleClick={this.zoomClick} />
  }

}

function Button({ handleClick }) {
  return <button onClick={handleClick()}>Click</button>
}

ReactDOM.render(
  <MyContainer /> ,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container"></div>

1 Comment

.binding zoomClick in the constructor is not even necessary in this case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.