ReactJS:通过表单获取和更新数据的惯用方法是什么?

时间:2015-05-12 19:19:53

标签: javascript reactjs flux

我试图围绕通过HTML表单更新数据的最佳方式。以ReactJS网页为例:

https://facebook.github.io/react/docs/tutorial.html

假设您希望实现用户编辑过去发布的评论的能力(即不在当前会话中,因此必须从服务器获取)。编辑评论页面需要预先填写评论的现有作者姓名和文字。您将如何实现获取评论数据并预先填写评论表单?以下是我头脑中存在的相互矛盾的想法,我无法解决(让我们调用新组件CommentEdit):

  • 最初的评论作者和文字应该是CommentEdit的道具,因为它们不是州
  • CommentEdit组件应该是可重用的,因此它应该能够从服务器本身获取初始数据,但是必须将其保存为状态
  • 如果CommentEdit的父级要抓取并为CommentEdit设置道具,则必须将其保存为状态,因此不会节省很多费用
  • 像Flux这样的东西可能有用,但Flux让我更加困惑。如果Flux要存储评论,是否必须保存用户的每条评论?如果用户有数千条评论,会发生什么?

老实说,我只是希望组件可以改变自己的道具。似乎它会使组件更具可重用性。

3 个答案:

答案 0 :(得分:1)

  

老实说,我只是希望组件可以改变自己的道具。似乎它会使组件更具可重用性。

不是真的,那些可以改变自己道具的组件并不是那么可以重复使用的组件,只是因为它们的底层实现会变得更加复杂。

数据下降和事件冒泡的当前$i<=14流使组件“非常”确定,因为在组件生命周期中的任何时候您都知道组件将根据您提供的输入生成哪些输出。在调试和单元测试应用程序时,这也有很大帮助。

现在,在你的困境中,react.js只需要CommentEdit属性,因为作者不会改变,并且永远是登录网站的人。其他状态不是必需的,因为当用户点击content按钮时,编辑的内容将被冒泡,并且当save列表存储在comments中时将被插入到列表中其中一个组件祖先将被更新。

如果你为每个评论正确设置state属性,那么react会很好地注意到编辑的评论的html元素不需要重新创建,只需要key提交评论的html元素需要更改。

如果您希望显示作者,可以将作者添加为道具,除非您想要使用此布局构建多个网站,否则它不会影响/改进组件本身。

答案 1 :(得分:0)

我最后通过添加&#34;包装&#34;来解决这个问题。每个组件的父级。包装器组件负责从服务器获取数据,它将以其状态存储。包装器将获取的状态作为道具传递给其子节点。然后我将这个设置抽象为mixins,创建一个包装mixin和wrapper child mixin,以便我可以轻松地重新使用这个设置。

此模式适用于您应用中的典型表单。包装器将获取数据以预先填充表单,子进程将表单发送到服务器并负责错误处理。

以下是一个例子:

// This handles the form submission and error handling
var EditFormMixin = {
  getInitialState: function() {
    return {formState:FORM_STATE_EDITING, errors:{}}
  },
  handleSubmitBase: function(event, url, data, method, success, error) {
    event.preventDefault();
    this.setState({formState:FORM_STATE_SUBMITTING, errors:{}});
    $.ajax({
        url: url,
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(data),
        method: method,
        success: function(data) {
            this.setState({formState:FORM_STATE_SUBMITTED});
            if (success) {
                success();
            };
        }.bind(this),
        error: function(xhr, status, err) {
            this.setState({formState:FORM_STATE_EDITING});
            if (xhr.status == 400) {
                this.setState({errors:xhr.responseJSON});
            }
            if (error) {
                error();
            }
        }.bind(this)
    });
  }
};

// This handles fetching the initial data for the form
var EditFormWrapperMixin = {
  getInitialState: function() {
    return {data: {}, loadState:LOAD_STATE_UNLOADED, url:this.getUrl()};
  },
  fetch: function() {
    this.setState({loadState:LOAD_STATE_LOADING})
    $.ajax({
        url: this.state.url,
        dataType: "json",
        method: "GET",
        success: function(data) {
            this.setState({data:data, loadState:LOAD_STATE_LOADED});
        }.bind(this),
        error: function(xhr, status, err) {
        }.bind(this)
    });
  }
  componentDidMount: function() {
    this.fetch();
  },
  componentWillReceiveProps: function(nextProps) {
    var url = this.getUrl();
    this.setState({url:url}, function() {
        this.fetch();
    });
  }
};

答案 2 :(得分:-2)

Flux是您可以用来从应用程序中获取数据的最佳工具,您不必使用组件内的状态,使用props来为初始数据收费,然后使用react.DOMNode从每个元素获取数据您需要https://facebook.github.io/react/docs/top-level-api.html#react.finddomnode的形式,也在所有表单组件中使用refs,最后您可以使用flux将数据发送到服务器并保存。