从 redux 操作重置表单状态
Reset form state from redux action
我目前有以下组件,为简单起见,我在 codesandbox here 上创建了一个最小示例。它证明了我的问题。
对于 Whosebug,这里有一些片段:
class CommentForm extends React.Component {
constructor(props) {
super(props);
this.state = {
comment: ""
};
this.handleCommentChange = this.handleCommentChange.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
}
handleCommentChange(evt) {
this.setState({ comment: evt.target.value });
}
handleFormSubmit(evt) {
evt.preventDefault();
this.props.addComment(this.state.comment);
}
render() {
const { submitting } = this.props;
return (
<form onSubmit={this.handleFormSubmit}>
<textarea
name="comment"
placeholder="Write your comment here..."
rows="5"
value={this.state.comments}
onChange={this.handleCommentChange}
/>
<br />
<input
type="submit"
disabled={submitting}
value="COMMENT"
/>
</form>
);
}
}
我的问题:当我的 saga 调度动作 COMMENT_ADD_SUCCESS
时,如何重置表单状态 (this.state.comments = ''
)?
我想避免的事情:在 redux 状态下添加评论。我知道我可以将评论移动到 redux 存储中,并且 return 类似于 {...state, commentField: ''}
的东西在 reducer 本身中。
为了演示目的,这个表单很简单,但我有一个复杂得多的表单,我觉得不需要将其添加到 redux 存储中,因为它的状态是短暂的,一旦组件死亡,状态可以简单地被丢弃。此外,如果我需要向商店添加评论,我需要创建像 COMMENT_UPDATED
这样的操作来更新 redux 商店,这可能是一个相当大的麻烦,尤其是对于具有很多字段的表单。
你能做这样的事情吗?
handleFormSubmit(evt) {
evt.preventDefault();
this.props.addComment(this.state.comment);
this.setState({ comments: ''});
}
扩展@Lefi 所说的内容:
您可以添加回调并在您的 saga.js 中调用它。
callback = () => {
this.setState({ comments : '' })
}
handleFormSubmit(comment, callback) {
...
}
下面的代码应该可以工作,因为您提供了 submitting
道具。你想要做的是捕捉从真到假的转变。
componentDidUpdate( prevProps ) {
if ( prevProps.submitting === this.props.submitting ) {
// The state of our comment submission hasn't changed so do nothing.
return;
}
if ( ! this.props.submitting ) {
// The comment just finished submitting because we
// we went from true to false
this.setState( { comments: '' } );
}
}
我通常将回调作为额外参数传递给操作,并从传奇中调用回调。因此,我将更改您的 CommentForm
代码以分派传递具有文本值和回调函数的对象的操作:
handleFormSubmit(evt) {
evt.preventDefault();
this.props.addComment({ comment: this.state.comment, callback: function() {
alert("callback invoked");
// here do cleanup of state as you wish
}});
}
并更改 saga 以在成功时调用回调:
function* addComment(params) {
console.log("Adding Comment");
yield put({ type: "ADD_COMMENT_FETCHING" });
// Simulate call success
yield call(delay, 5000);
alert("(From saga) The comment was added successfully.");
yield put({ type: "ADD_COMMENT_SUCCESS" });
params.action.callback(); // <--- here the callback
}
Redux 状态未受影响,您还可以考虑添加第二个回调,在 saga 中 failure/error 时将调用该回调。
我fork了你的sandbox,你可以查看代码here
我目前有以下组件,为简单起见,我在 codesandbox here 上创建了一个最小示例。它证明了我的问题。
对于 Whosebug,这里有一些片段:
class CommentForm extends React.Component {
constructor(props) {
super(props);
this.state = {
comment: ""
};
this.handleCommentChange = this.handleCommentChange.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
}
handleCommentChange(evt) {
this.setState({ comment: evt.target.value });
}
handleFormSubmit(evt) {
evt.preventDefault();
this.props.addComment(this.state.comment);
}
render() {
const { submitting } = this.props;
return (
<form onSubmit={this.handleFormSubmit}>
<textarea
name="comment"
placeholder="Write your comment here..."
rows="5"
value={this.state.comments}
onChange={this.handleCommentChange}
/>
<br />
<input
type="submit"
disabled={submitting}
value="COMMENT"
/>
</form>
);
}
}
我的问题:当我的 saga 调度动作 COMMENT_ADD_SUCCESS
时,如何重置表单状态 (this.state.comments = ''
)?
我想避免的事情:在 redux 状态下添加评论。我知道我可以将评论移动到 redux 存储中,并且 return 类似于 {...state, commentField: ''}
的东西在 reducer 本身中。
为了演示目的,这个表单很简单,但我有一个复杂得多的表单,我觉得不需要将其添加到 redux 存储中,因为它的状态是短暂的,一旦组件死亡,状态可以简单地被丢弃。此外,如果我需要向商店添加评论,我需要创建像 COMMENT_UPDATED
这样的操作来更新 redux 商店,这可能是一个相当大的麻烦,尤其是对于具有很多字段的表单。
你能做这样的事情吗?
handleFormSubmit(evt) {
evt.preventDefault();
this.props.addComment(this.state.comment);
this.setState({ comments: ''});
}
扩展@Lefi 所说的内容:
您可以添加回调并在您的 saga.js 中调用它。
callback = () => {
this.setState({ comments : '' })
}
handleFormSubmit(comment, callback) {
...
}
下面的代码应该可以工作,因为您提供了 submitting
道具。你想要做的是捕捉从真到假的转变。
componentDidUpdate( prevProps ) {
if ( prevProps.submitting === this.props.submitting ) {
// The state of our comment submission hasn't changed so do nothing.
return;
}
if ( ! this.props.submitting ) {
// The comment just finished submitting because we
// we went from true to false
this.setState( { comments: '' } );
}
}
我通常将回调作为额外参数传递给操作,并从传奇中调用回调。因此,我将更改您的 CommentForm
代码以分派传递具有文本值和回调函数的对象的操作:
handleFormSubmit(evt) {
evt.preventDefault();
this.props.addComment({ comment: this.state.comment, callback: function() {
alert("callback invoked");
// here do cleanup of state as you wish
}});
}
并更改 saga 以在成功时调用回调:
function* addComment(params) {
console.log("Adding Comment");
yield put({ type: "ADD_COMMENT_FETCHING" });
// Simulate call success
yield call(delay, 5000);
alert("(From saga) The comment was added successfully.");
yield put({ type: "ADD_COMMENT_SUCCESS" });
params.action.callback(); // <--- here the callback
}
Redux 状态未受影响,您还可以考虑添加第二个回调,在 saga 中 failure/error 时将调用该回调。 我fork了你的sandbox,你可以查看代码here