Reputation: 5
I'm trying to simulate the way the form was submitted. So to summarize when the user types in the textarea
'field, the component must be updated, then the user presses the submit button and the component is updated again. I expect that the value filled in the textarea will be empty after the user successfully submit. But unexpectedly the returned value is undefined
.
CommentBox.js
import React from 'react';
class CommentBox extends React.Component {
state = {
comment: ''
}
handleChange = event => {
this.setState({
comment: event.target.value
})
}
handleSubmit = event => {
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<h4>Add a comment</h4>
<textarea onChange={this.handleChange} value={this.state.comment} />
<div>
<button>Submit Comment</button>
</div>
</form>
)
}
}
export default CommentBox;
CommentBox.text.js
import React from 'react';
import { mount } from 'enzyme';
import CommentBox from 'components/CommentBox';
let wrapped;
beforeEach(() => {
wrapped = mount(<CommentBox />);
})
afterEach(() => {
wrapped.unmount();
})
it('when form is submitted, text area gets emptied', () => {
wrapped.find('textarea').simulate('change', {
target: { value: 'new comment' }
})
wrapped.update();
wrapped.find('form').simulate('submit', {
preventDefault: () => {}
});
wrapped.update();
expect(wrapped.find('textarea').prop('value')).toEqual('');
})
I expect the output will be passed but the actual output is value returns undefined so test is failed.
Upvotes: 0
Views: 357
Reputation: 26
You may try this:
import React from 'react';
class CommentBox extends React.Component {
//adding initVal for setting initial value in textbox
// and playing with it until the form submits
state = {
comment: '',
initVal: ''
}
handleChange = event => {
//on change in textfield, updating initVal with the typed text
this.setState({
initVal: event.target.value
})
}
handleSubmit = event => {
//finally on submission comment is updated with entered value
//which you may use it for further operations
//and initVal is set back to empty '' for setting textfield value as empty
//field
this.setState({
comment: this.state.initVal
initVal: ''
})
//event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<h4>Add a comment</h4>
//changes here
<textarea onChange={this.handleChange} value={this.state.initVal} />
<div>
<button>Submit Comment</button>
</div>
</form>
)
}
}
export default CommentBox;
Upvotes: 0
Reputation: 19762
I don't see anything that would make the test fail... other than not including this.setState({ comment: "" });
in the handleSubmit
callback.
If you utilize state
, then you have to manually reset it (or if the component unmounts, then it loses state
automatically). React works by manipulating a virtual DOM
. Then, you utilize state
to manipulate the elements within this virtual DOM
. Since you're preventing a page refresh (e.preventDefault
) the state
persists as intended.
Working example (click the Tests
tab -- next to the Browser
tab -- to run the test):
components/CommentBox
import React, { Component } from "react";
class CommentBox extends Component {
state = { comment: "" };
handleChange = ({ target: { value } }) => {
this.setState({ comment: value });
};
handleSubmit = e => {
e.preventDefault();
console.log("submitted comment: ", this.state.comment);
this.setState({ comment: "" });
};
render = () => (
<div className="app">
<form onSubmit={this.handleSubmit}>
<h4>Add a comment</h4>
<textarea
className="uk-textarea"
onChange={this.handleChange}
value={this.state.comment}
/>
<div className="button-container">
<button type="submit" className="uk-button uk-button-primary">
Submit Comment
</button>
</div>
</form>
</div>
);
}
export default CommentBox;
components/CommentBox/__tests__/CommentBox.test.js
import React from "react";
import { mount } from "enzyme";
import CommentBox from "../index";
describe("Comment Box", () => {
let wrapper;
beforeEach(() => {
wrapper = mount(<CommentBox />);
});
afterEach(() => {
wrapper.unmount();
});
it("when form is submitted, text area gets emptied", () => {
wrapper.find("textarea").simulate("change", {
target: { value: "new comment" }
});
expect(wrapper.find("textarea").prop("value")).toEqual("new comment");
wrapper.find("form").simulate("submit", {
preventDefault: () => {}
});
expect(wrapper.find("textarea").prop("value")).toEqual("");
});
});
Upvotes: 1
Reputation: 664
handleChange = (e) => {
if(e.keyCode == 13 && e.shiftKey == false) {
e.preventDefault();
this.myFormRef.submit();
}
}
render() {
return (
<form ref={el => this.myFormRef = el} >
<h4>Add a comment</h4>
<textarea onKeyDown={this.handleChange} value={this.state.comment}
/>
<div>
<button type="submit">Submit Comment</button>
</div>
</form>
);
}
you can do like this on enter
Upvotes: 0