Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - Cannot read property 'call' of undefined

Everything seems to work with this small app except adding a new note. Button is located on the Board component.

i know this problem is usually caused by not binding value of 'this' properly. I'm not sure if that's the issue here or if i'm missing something else. Thanks

Demo: http://jsbin.com/pewahi/edit?js,output

/* jshint asi:true */

class Note extends React.Component {
  constructor(props) {
    super(props)
    this.state = { editing: props.editing }
  }

  render() {
    if (this.state.editing) {
      return this.renderForm()
    } else {
      return this.renderDisplay()
    }
  }

  edit() {
    this.setState({editing: true})
  }

  save() {
    this.props.changeHandler(this.refs.newText.getDOMNode().value, this.props.index)
    this.setState({editing: false})
  }

  remove() {
    this.props.removeHandler(this.props.index)
  }

  renderDisplay() {
     return (      
      <div className="note">
        <p>{this.props.children}</p>
        <span>
          <button className="btn btn-sm glyphicon glyphicon-pencil" onClick={this.edit.bind(this)}></button>
          <button className="btn btn-sm glyphicon glyphicon-trash" onClick={this.remove.bind(this)}></button>
        </span>
      </div>   
    )    
  }

  renderForm() {
    return (
      <div className="note">
        <textarea ref="newText" defaultValue={this.props.children} className="form-control"></textarea>
        <button onClick={this.save.bind(this)} className="btn btn-success btn-sm"><span className="glyphicon glyphicon-floppy-disk"></span> Save</button>
      </div>
    )
  }
}

Note.propTypes = { 
  editing: React.PropTypes.bool,
  onChange: React.PropTypes.func,
  onRemove: React.PropTypes.func
}

Note.defaultProps = { editing: false }

class Board extends React.Component {
  constructor(props) {
    super(props)
    this.state = { 
      notes: [{note: 'hi', id: this.nextId()}]
    }
  }

  update(newText, i) {
    var arr = this.state.notes
    arr[i].note = newText
    this.setState({notes: arr})
  }

  remove(i) {
    var arr = this.state.notes
    arr.splice(i, 1)
    this.setState({notes: arr})
  }

  addNote(text) {
    var arr = this.state.notes
    arr.push({
      id: this.nextId(),
      note: text
    })
    console.log(arr)
    this.setState({notes: arr})
  }

  nextId() {
    this.uniqueId = this.uniqueId || 0
    return ++this.uniqueId
  }


  eachNote(note, i) {
    return (
      <Note key={note.id}
            index={i}
            changeHandler={this.update.bind(this)}
            removeHandler={this.remove.bind(this)}

        >{note.note}
      </Note>
    )
  }

  render() {
    return (
      <div className="board">
        {this.state.notes.map(this.eachNote, this)}
        <button onClick={this.addNote.bind(this, "new note")} className="btn btn-success btn-sm glyphicon glyphicon-plus"></button>
      </div>
    )
  }
}

React.render(
  <Board />,
  document.getElementById('message-board')
)
like image 633
user5406969 Avatar asked Oct 04 '15 15:10

user5406969


People also ask

How do you fix Cannot read property of undefined in react?

The "Cannot read property 'props' of undefined" error occurs when a class method is called without having the correct context bound to the this keyword. To solve the error, define the class method as an arrow function or use the bind method in the classes' constructor method.


2 Answers

Your code is fine. This is likely a bug with JSBin, and how it handles transpilation with Babel. If you add the pragma // noprotect to the top of your code you will see that it works.

like image 164
lukewestby Avatar answered Sep 28 '22 10:09

lukewestby


I was facing the same error. I was using a base component and I noticed that I had removed componentDidMount method of the base component. And when I call super.componentDidMount in sub component it was giving the error. So I have removed super call and problem solved.

like image 29
Olcay Ertaş Avatar answered Sep 28 '22 12:09

Olcay Ertaş