Reputation:
Please don't mark it as duplicate first please read my question, I tried bind my function in constructor and also tried to bind in return but still i'm getting the error that "Cannot read property 'bind' of undefined."When i remove bind from constructor it gave me error of updateComment.I mean to say that i tried to bind this but nothing helps.
COde:
<!Doctype html>
<html>
<head>
<title>React Practice</title>
<link rel="stylesheet" href="main.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
</head>
<body>
<script type="text/jsx">
class Basics extends React.Component
{
constructor () {
super();
this.state = {editing:false};
}
edit () {
this.setState({editing:true});
}
save () {
this.setState({editing:false});
this.props.upComment(this.refs.newText.value, this.props.index);
}
remove () {
this.props.delComment(this.props.index);
}
renderNormal () {
return (
<div>
<div className="commentText">{this.props.children}</div>
<button onClick={this.edit.bind(this)} className="button-primary">Edit</button>
<button onClick={this.remove.bind(this)} className="button-danger">Remove</button>
</div>
)
}
renderForm () {
return (
<div>
<textarea ref='newText' defaultValue={this.props.children}></textarea>
<button onClick={this.save.bind(this)} className="button-success">Save</button>
</div>
)
}
render () {
if (this.state.editing) {
return this.renderForm();
} else {
return this.renderNormal();
}
}
}
class Manage extends React.Component {
constructor (props) {
super(props);
this.removeComment = this.removeComment.bind(this);
this.upComment = this.upComment.bind(this);
this.state = {
comments: [
'This is a first comment',
'Hi there!',
'I am learning React'
]
}
}
removeComment(i) {
console.log(i);
var arr = this.state.comments;
arr.splice(i, 1);
this.setState({comments: arr})
}
updateComment(newText, i) {
console.log('Updating Comment');
var arr = this.state.comments;
arr[i] = newText;
this.setState({comments: arr})
}
render () {
return (
<div className="board">
{this.state.comments.map(function (text,i) {
return (<Basics key={i} index={i} upComment={this.updateComment} delComment={this.removeComment}>
{text}
</Basics>)
}
)}
</div>
)
}
};
ReactDOM.render(<Manage />, document.getElementById('example'));
</script>
<div id="example"></div>
</body>
</html>
Upvotes: 0
Views: 2013
Reputation: 19194
There are multiple errors in your code that needed solving.
upComment
does not exist in your code. What you should bind is the function itself (updateComment
) and not the prop name.If you are using this
variable inside any function, it needs to be bound. This is the case in renderNormal
and renderForm
.
When you are using this
inside the render function of Manage, you were using an anonymous callback. But then this
would bind to this callback rather than the class function. Changing this to a arrow function works.
class Basics extends React.Component {
constructor() {
super();
this.state = { editing: false };
this.renderNormal = this.renderNormal.bind(this);
this.renderForm = this.renderForm.bind(this);
}
edit() {
this.setState({ editing: true });
}
save() {
this.setState({ editing: false });
this.props.upComment(this.refs.newText.value, this.props.index);
}
remove() {
this.props.delComment(this.props.index);
}
renderNormal() {
return (
<div>
<div className="commentText">{this.props.children}</div>
<button onClick={this.edit.bind(this)} className="button-primary">Edit</button>
<button onClick={this.remove.bind(this)} className="button-danger">Remove</button>
</div>
)
}
renderForm() {
return (
<div>
<textarea ref='newText' defaultValue={this.props.children}></textarea>
<button onClick={this.save.bind(this)} className="button-success">Save</button>
</div>
)
}
render() {
if (this.state.editing) {
return this.renderForm();
} else {
return this.renderNormal();
}
}
}
class Manage extends React.Component {
constructor(props) {
super(props);
this.removeComment = this.removeComment.bind(this);
this.updateComment = this.updateComment.bind(this);
this.state = {
comments: [
'This is a first comment',
'Hi there!',
'I am learning React'
]
}
}
removeComment(i) {
console.log(i);
var arr = this.state.comments;
arr.splice(i, 1);
this.setState({ comments: arr })
}
updateComment(newText, i) {
var arr = this.state.comments;
arr[i] = newText;
this.setState({ comments: arr })
}
render() {
return (
<div className="board">
{this.state.comments.map((text, i)=> {
return (
<Basics key={i} index={i} upComment={this.updateComment} delComment={this.removeComment}>
{text}
</Basics>)
}
)}
</div>
)
}
};
ReactDOM.render(<Manage />, document.getElementById("example"));
<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="example"></div>
Upvotes: 2
Reputation: 1093
Your function name is updateComment
while defining the function but when you're binding the context of the class to the function, the name you're using is upComment
(class Manage
, 3rd line in it's constructor
) which is why you're getting the error.
Upvotes: 1
Reputation: 1
One issue is that .bind()
call at global attribute event would result in function () { [native code] }
instead of the function call, and this
is the global object, for example window
.
One approach would be to define edit
and remove
as static
methods and use the class
as a reference
class Test {
constructor() {}
static edit() { console.log("edit") }
renderNormal() {
const button = `<div onclick="Test.edit()">click</div>`;
document.body.insertAdjacentHTML("beforeend", button);
}
}
new Test().renderNormal()
Upvotes: 0
Reputation: 1240
I think there is no need to bind methods/functions in the constructor instead do this
return (
<Basics key={i}
index={i}
upComment={()=>this.updateComment()}
delComment={()=>this.removeComment()}>
{text}
</Basics>)
While assigning the props wrap your functions into anonymous functions it may help i didn't try this.
Upvotes: 0