我正在尝试模拟表单的提交方式。因此,总结一下,当用户在textarea
字段中键入内容时,必须更新组件,然后用户按下Submit按钮,然后再次更新组件。我希望用户成功提交后,textarea中填充的值将为空。但是意外地,返回值是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('');
})
我希望输出将通过,但实际输出是value返回未定义,因此测试失败。
答案 0 :(得分:1)
除了没有在this.setState({ comment: "" });
回调中包含handleSubmit
之外,我没有看到任何会导致测试失败的事情。
如果您使用state
,则必须手动将其重置(或者,如果卸下组件,则它会自动丢失state
)。 React通过操纵虚拟DOM
来工作。然后,您利用state
来操纵该虚拟DOM
中的元素。由于您要阻止页面刷新(e.preventDefault
),因此state
会按预期保留。
工作示例(单击Tests
标签旁边的Browser
标签—运行测试):
组件/注释框
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("");
});
});
答案 1 :(得分:0)
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>
);
}
您可以在Enter上这样做
答案 2 :(得分:0)
您可以尝试以下方法:
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;