从Redux动作重置表单状态

时间:2018-07-09 19:26:39

标签: javascript reactjs redux redux-saga

我目前具有以下组件,为简单起见,我在 codesandbox here 上创建了一个最小示例。它说明了我的问题。

对于stackoverflow,这是一些片段:

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>
    );
  }
}

我的问题:我的传奇人物调度动作this.state.comments = ''时,如何重置表单状态(COMMENT_ADD_SUCCESS)?

我要避免的事情:在redux状态下添加评论。我知道我可以将注释移入redux存储,并在化简器中返回类似{...state, commentField: ''}的内容。

此表单很简单,仅用于演示目的,但是我有一个复杂得多的表单,我觉得不需要将其添加到redux存储中,因为它的状态是短暂的,一旦组件死亡,该状态可以简单地丢弃。此外,如果我需要在商店中添加评论,则需要创建COMMENT_UPDATED之类的操作来更新redux存储,这可能是一个很大的麻烦,尤其是对于具有许多字段的表单而言。

3 个答案:

答案 0 :(得分:2)

我通常将回调作为额外的参数传递给操作,然后从传奇中调用回调。因此,我将更改您的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
    }});
  }

并更改传奇,以在成功时调用回调:

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状态保持不变,您还可以考虑添加第二个回调,以在传奇中发生故障/错误时调用。 我为您的沙箱创建了分叉,您可以检查代码here

答案 1 :(得分:1)

由于您提供了submitting道具,因此下面的代码应该可以工作。您要做的就是捕获从true到false的过渡。

  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: '' } );
    }

    
  }

答案 2 :(得分:0)

您能做这样的事情吗?

  handleFormSubmit(evt) {
    evt.preventDefault();
    this.props.addComment(this.state.comment);
    this.setState({ comments: ''});
  }

要扩展@Lefi所说的话:

您可以添加一个回调并在您的saga.js中调用它。

callback = () => {
  this.setState({ comments : '' })
}

handleFormSubmit(comment, callback) {
  ...
}