Everything seems to work with this small app except adding a new note. Button is located on the Board ponent.
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: ,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')
)
Everything seems to work with this small app except adding a new note. Button is located on the Board ponent.
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./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')
)
Share
Improve this question
asked Oct 4, 2015 at 15:01
user5406969user5406969
931 gold badge1 silver badge3 bronze badges
1
- Are there legitimate "fix my code" questions? – Basilevs Commented Oct 4, 2015 at 15:09
3 Answers
Reset to default 8Your 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.
I was facing the same error. I was using a base ponent and I noticed that I had removed ponentDidMount
method of the base ponent. And when I call super.ponentDidMount
in sub ponent it was giving the error. So I have removed super call and problem solved.
Binding this is something of a hassle with ES6
classes in React
. One way is to bind them in your constructor like so;
constructor(props) {
super(props)
this.nextid = this.nextid.bind(this)
this.state = {
notes: [{note: 'hi', id: this.nextId()}]
}
}
Another is to use babel.configure({stage: 0})
and arrow functions.
nextid = () => {}