2

Below is my code. My onClick is nor working. It always through error "Uncaught TypeError: Cannot read property 'likeQuestion' of undefined". But my "gotoPage" function is working. I don't know where I am wrong. I am very new in Reactjs. Why "likeQuestion" function is not recognized.

My first onClick is working

export default class Question extends React.Component {
  constructor(){
    super();
    this.toggle = this.toggle.bind(this);
    this.state = {
        pageNo : 1,
        dropdownOpen: false,
        questioninfo : []
      }
  }
  componentWillMount(){
     //some action
  }

  gotoPage(index) {

      //some action. This is working
    }

  toggle() {
    this.setState({
      dropdownOpen: !this.state.dropdownOpen
    });
  }

 likeQuestion(e){
    console.log('this is clicked');
    //But this is not working
 }


render() {
        var canvases = this.state.questionItem.map(function(data,i) {
          var firstLtr = data.user_name.charAt(0);

            return (
               <div key={i}>
                     <Col sm="12" md={{ size: 12, offset: 2 }} className="questionCard">
                      <Card block>
                        <CardTitle>
                                <div className="outerCircle"><span>{firstLtr}</span></div> {data.user_name}
                                <i className="fa fa-flag-o flagging" aria-hidden="true"></i>
                                <a href={data.location_url} target="_blank" className="questionLocation">{data.location_url}</a>
                        </CardTitle>
                        <CardText className="questionTxt">{data.message}</CardText>
                        <div>
                             <Button className="replyBtn" disabled>No Discussion</Button>
                             <Button size="sm" color="link" className="disussionSpan" onClick={(i) => this.likeQuestion(i)}>{data.likes} Likes</Button>
                        </div>
                      </Card>
                    </Col>
               </div>
            );
       });

    return(
      <div className="container">
        <div className="row">
        <div className="pageInfo">
        <Dropdown className="inline" isOpen={this.state.dropdownOpen} toggle={this.toggle}>
          <DropdownToggle caret>
            Pages
          </DropdownToggle>
          <DropdownMenu>
            {pgrow}
          </DropdownMenu>
        </Dropdown>
        <p className="inline currPgNo">Page: {currentPage}</p>
        </div>
            <div className="col-md-8 col-md-offset-2">

                {canvases}
            </div>
        </div>

      </div>
    )
  }

2 Answers 2

2

React wouldn't auto-bind map inside render(), so you have to do it yourself in order to use this and call this.likeQuestion. Luckily, map provides a second argument to specify the context (this).


So just use...

this.state.questionItem.map(function(data,i) {
  ...
}, this)

instead of

this.state.questionItem.map(function(data,i) {
  ...
})
  • Option 2: Use arrow function in the map, such as map((data, i) => ...

  • Option 3: bind this to likeQuestion in the constructor of the component.

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

7 Comments

Adding this worked cool thank you. Can you explain me why it worked?
React simply wouldn't auto-bind the map method inside render() so you have to do it yourself
glad to help;-)
can you help me on one more thing I am passing the argument which is being fetched by an api onclick is being clicked while page is loaded. onClick={this.likeQuestion(this,data.question_url)}
You need onClick={()=>this.likeQuestion(this, data.question_url)} . Post a new question if still unclear
|
2

Try to define your helper functions using arrow functions

 gotoPage = (index) => {

      //some action. This is working
    }

  toggle = () => {
    this.setState({
      dropdownOpen: !this.state.dropdownOpen
    });
  }

 likeQuestion = (e) => {
    console.log('this is clicked');
    //But this is not working
 }

or

Bind these methods in constructor of your React component. e.g

this.likeQuestion = this.likeQuestion.bind(this);
// Needs to be done for all the helper methods.

So that you access the class level this context.

E.g a minimal setup

class Question extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      likes:10
    };
  }


  likeQuestion = (e) => {
    
    console.log('this is clicked');
    //But this is not working
  }
  render() {

    return ( < div >
      < button size = "sm"
      color = "link"
      className = "disussionSpan"
      onClick = {
        (i) => this.likeQuestion(i)
      } > {
        this.state.likes
      }
      Likes < /button>

          < /div >
    );
  }

};

ReactDOM.render( < Question / > , document.querySelector('#test'));
<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="test">
</div>

4 Comments

Updated answer with an example.
Now i m getting it right. aftr adding this in render.
Thank you for your help.
can you help me on one more thing I am passing the argument which is being fetched by an api onclick is being clicked while page is loaded. onClick={this.likeQuestion(this,data.question_url)}

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.