【问题标题】:How to add or delete objects from React - Rails?如何从 React - Rails 添加或删除对象?
【发布时间】:2016-09-17 21:57:14
【问题描述】:

我有一个带有 react-rails gem 的 Rails 应用程序。

这是我的控制器:

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添加Website组件来获取服务器上的数据:

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

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

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

【问题讨论】:

  • 我不确定我是否理解,但是你不能在 done 回调中使用 React 的 setState 来改变组件的状态吗?
  • 我尝试过这样做——就像现在我从 PropTypes 网站获得的“this.props.websites”:React.PropTypes.node。我试图这样做。state = {websites: ...} 但没有弄清楚应该是什么而不是三个点。
  • 哦,我马上就会给出答案。
  • 我实际上是通过在构造函数中传递一个参数来管理它,但现在我正在考虑如何添加网站并更新 this.state.websites
  • 你能分享源代码以便我在同一页面上吗?

标签: ruby-on-rails ajax reactjs react-rails


【解决方案1】:

好的,所以您真正想要的是在 AddWebsite 组件中从您保存应用程序状态的 Dashboard 传递一个回调。请注意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
};

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

【讨论】:

    猜你喜欢
    • 2017-06-13
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 2022-01-24
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多