我有三个React组件:第一个是容器(NoteContainer组件),它负责在UI中呈现我的对象(Note组件)。数据通过AJAX GET作为JSON获得。最后一个组件是窗体(NoteForm),该窗体创建新对象(通过AJAX POST)。

POST的响应仅是新创建对象的JSON表示,而不是所有对象的JSON。

NoteForm应该将创建新对象后的JSON响应发送到NoteContainer,将其附加到其state.data并重新呈现,或者NoteContainer请求对象的完整列表并更新其状态日期完全?

我认为第一种方法更好,因为它不需要请求在NoteContainer状态下已经存在的数据。但是,我仍然不确定处理此问题的“最佳”方法。我应该给NoteContainer另一个函数,例如addNewNote,该函数将从NoteForm中获取JSON数据并将其附加到state.data吗?

我是React的新手,如果这个问题不清楚,我深表歉意。这是我的组件:

var NoteContainer = React.createClass({
  getInitialState: function(){
    return {data: []};
  },
  componentDidMount: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data){
        this.setState({data: data});
      }.bind(this),
      error: function(xhr, status, err){
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
  render: function(){
    var noteNodes = this.state.data.map(function(note){
      return (
        <Note title={note.title} body={note.body} />
      );
    });
    return (<div className='noteContainer'>{noteNodes}</div>);
  }
});

var Note = React.createClass({
  render: function(){
    return (
      <div className="note" >
        <h1>{this.props.title}</h1>
        <p>{this.props.body}</p>
      </div>
    );
  }
});


var NoteForm = React.createClass({
  getInitialState: function(){
    return {'title': '', 'body': ''}
  },
  handleTitleChange: function(e){
    this.setState({title: e.target.value});
  },
  handleBodyChange: function(e){
    this.setState({body: e.target.value});
  },

  handleSubmit: function(e){
    e.preventDefault();
    var note = {
      title: this.state.title,
      body: this.state.body};
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: note,
      success: function(data){
        // Send data to NoteContainer?
      }.bind(this),
      error: function(xhr, status, err){
        console.error(this.props.url, status, err.toString());
      }.bind(this)
  });
},

  render: function(){
    return (
      <form>
        <input
          type='text'
          placeholder='Title'
          value={this.state.title}
          onChange={this.handleTitleChange} />
        <textarea onChange={this.handleBodyChange}>
          {this.state.body}
        </textarea>

      </form>
    );
  }
});

最佳答案

@xCrZx的建议是您将状态拉到各个组件之外,并拥有一个或多个顶级存储来维护状态。最简单的示例(即“香草”)是您的NoteContainerNoteForm的父级。然后,您可以简单地将回调从NoteContainer传递到NoteForm

var NoteContainer = React.createClass({
  createNote: function() {
    ...
  },
  render: function() {
    return (
      ...
      <NoteForm createNote={this.createNote}>
      ...
    );
  }
});

var NoteForm = React.createClass({
  props: {
    createNote: React.PropTypes.func.isRequired
  },
  render: function() {
    return (
      ...
        onClick={this.props.createNote}
      ...
    );
  }
});


但是,只有在实际存在该关系的情况下,该方法才有效。现在,让我们看一下Reflux,在其中创建中心存储(以及与之相关的操作)以保存数据,并使组件“监听”存储。

var NoteActions = Reflux.createActins([
  'createNote',
  'getNotes'
]);

var NoteStore = Reflux.createStore({
  listenables: [NoteActions],
  init: {
    // Notes is an empty array by default
    this.notes = [];
  },
  getInitialState: function() {
    return {
      notes: this.notes
    };
  },
  onCreateNote: function(noteFormData) { ...POST here, save note JSON to this.notes on success... },
  onGetNotes: function() { ..GET here for the initial load...}
});

var NoteForm = React.createClass({
  render: function() {
    ...
      onClick={NoteActions.createNote(noteFormData)}
    ...
  }
});

var NoteContainer = React.createClass({
  mixins: [Reflux.connect(NoteStore)],
  componentDidMount: function() {
    NoteActions.getNotes();
  },
  render: function() {
    return: function() {
      .. same that you have now using this.state.notes
    }
  }
});


希望这开始有意义。强烈建议您仔细阅读Reflux(或Redux,相似但不同)的示例。

07-24 09:19