如何从 React 添加或删除对象 - Rails?

How to add or delete objects from React - Rails?

我有一个 Rails 应用 react-rails gem。

这是我的控制器:

class WebsitesController < ApplicationController
  def index
    @websites = Website.all
  end
end

这是我的观点:

<%= react_component('WebsiteList', websites: @websites) %>

这是我的 React 组件:

class WebsiteList extends React.Component {

  render () {
    return (
      <div className="container">
        <AddWebsite/>
        <WebsiteItem websites={this.props.websites}/>
      </div>
    );
  }
}

WebsiteList.propTypes = {
  websites: React.PropTypes.node
};

在 WebsiteItem 中,它只是映射数组并显示每个对象。

使用 ajax 添加网站组件以获取服务器上的数据:

class AddWebsite extends React.Component {
  constructor() {
    super();
    this.state = {
      formValue: "http://www."
    }
  }

  handleChange(e) {
    this.setState({formValue: e.target.value});
  }

  submitForm() {
    $.ajax({
      method: "POST",
      url: "/websites",
      data: { website: {name: "New Web", url: this.state.formValue} }
    })
      .done(function() {
        console.log("done")
      });
  }

  render() {
    return (
      <form>
        <input value={this.state.formValue} onChange={this.handleChange.bind(this)} name="url"/>
        <button type="button" onClick={this.submitForm.bind(this)} className="btn">Add Web</button>
      </form>
    );
  }
}

当有人添加(或删除)一个 link 并且 ajax 成功时,我也想更新 React 组件。而不是 this.props.websites & propTypes - 我怎么能为状态做呢?我需要从 ajax 获取它还是可以在 erb 中使用 <%=react_component ... %>

解决它并创建基本上是单页应用程序的最佳方法是什么?

好的,所以您真正想要的是在从保存应用程序状态的 Dashboard 传递的 AddWebsite 组件中有一个回调。请注意 this.state 是组件绑定的,这意味着您无法访问另一个组件的状态。您可以将一个组件的状态作为 属性 传递给另一个组件,这就是我们将要使用的。

// dashboard.es6.jsx
class Dashboard extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      websites: this.props.websites
    }

    // Don't forget to bind to self
    this.handleWebsiteAdd = this.handleWebsiteAdd.bind(this)
  }

  handleWebsiteAdd(newWebsite) {
    const websites = this.state.websites.concat([newWebsite]);

    this.setState({websites});       
  }

  render() {
    return (
      <div className="container">
        <AddWebsite onAdd={this.handleWebsiteAdd}/>
        <WebsiteList websites={this.state.websites}/>
      </div>
    );
  }
}

// add_website.es6.jsx
class AddWebsite extends React.Component {
  constructor() {
    super();
    this.state = {
      formValue: "http://www."
    }
  }

  handleChange(e) {
    this.setState({formValue: e.target.value});
  }

  submitForm() {
    $.ajax({
      method: "POST",
      url: "/websites",
      data: { website: {name: "New Web", url: this.state.formValue} }
    })
      .done(function(data) {
        // NOTE: Make sure that your API endpoint returns new website object
        // Also if your response is structured differently you may need to extract it 
        // and instead of passing data directly, pass one of its properties.
        this.props.onAdd(data)
        Materialize.toast('We added your website', 4000)
      }.bind(this))
      .fail(function() {
        Materialize.toast('Not a responsive URL', 4000)
      });
  }

  render() {
    return (
      <div className="card">
        <div className="input-field" id="url-form">
          <h5>Add new website</h5>
          <form>
            <input id="url-input" value={this.state.formValue} onChange={this.handleChange.bind(this)} type="text" name="url"/>
            <button type="button" onClick={this.submitForm.bind(this)} className="btn">Add Web</button>
          </form>
        </div>
      </div>
    );
  }
}

AddWebsite.propTypes = {
  onAdd: React.PropTypes.func.isRequired
};

请注意,这只是众多可能解决方案中的一种。