В приложении React-Rails передача переменных экземпляра от контроллера к компоненту (и обратно)

Я создаю приложение React-Rails, используя ES6, и у меня возникают трудности с передачей данных из контроллера в компонент (и обратно).

Мое приложение содержит форму записи, которая помещает вновь созданную запись в компонент записей.

Код в моем контроллере записей:

class RecordsController < ApplicationController
    def index
        @records = Record.all
    end

    def create
        @record = Record.new(record_params)

        if @record.save
            render json: @record
        else 
            render json: @record.errors, status: :unprocessable_entity
        end

    end


    private
        def record_params
            params.require(:record).permit(:title, :date, :amount)
        end

end

Код для компонента "Записи":

class Records extends React.Component {
    constructor (props) {
        super(props);

    }
    componentWillMount () {
        var records = this.records;
        this.state = {records: records};
    }
    addRecord (record) {
        var records;
        records = this.state.records;
        records.push(record);
        this.setState({records: records});
    }
      render () {
        var records = this.records.map(function(record) {
                        return <Record key={record.id} data={record} />;
                        });

        return (        
                <div>
                    <h2>Records</h2>
                    <RecordForm handleNewRecord={this.addRecord()} />
                    <table>
                        <thead>
                            <tr>
                                <th>Title</th>
                                <th>Date</th>
                                <th>Amount</th>
                            </tr>
                        </thead>
                        <tbody>
                            {records}
                        </tbody>
                    </table>
                </div>
        );
      }
}

Код для компонента "Форма записи":

class RecordForm extends React.Component {
  constructor (props) {
    super (props);
    this.state = {
      title: "",
      date: "",
      amount: ""
    }
    this.handleNewRecord = this.props.handleNewRecord.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange (e) {
    var stateObject = function() {
      returnObj = {};
      returnObj[this.target.name] = this.target.value;
         return returnObj;
    }.bind(e)();

    this.setState( stateObject ); 
    }

  handleSubmit (e) {
    e.preventDefault();
    $.ajax({
      type: 'POST',
      url: '',
      data: {record: this.state},
      success: function (data) {
                  this.props.handleNewRecord();
                  this.setState({title: "", date: "", amount: ""})
              },
      dataType: 'JSON'
    });
  }
  render () {
    return (
          <form className="form-inline" onSubmit={this.handleSubmit} >
            <div className="form-group">
              <input  
                type="text" 
                className="form-control text" 
                placeholder="Date"
                name="date"
                value={this.state.date}
                onChange={this.handleChange}
              />
              </div>
            <div className="form-group">
              <input  
                type="text" 
                className="form-control" 
                placeholder="Title"
                name="title"
                value={this.state.title}
                onChange={this.handleChange}
              />
            </div>
            <div className="form-group">
              <input  
                type="text" 
                className="form-control" 
                placeholder="Amount"
                name="amount"
                value={this.state.amount}
                onChange={this.handleChange}
              />
            </div>
            <input 
                type="submit" 
                value="Create Record"
                className="btn btn-primary"
            />
          </form>
    );
  }
}

Код для компонента записи:

class Record extends React.Component {
  render () {
    return (
      <tr>
        <td><em>{this.props.data.title}</em></td>
        <td>{this.props.data.date}</td>
        <td>{this.props.data.amount}</td>
      </tr>
    );
  }
}

Когда я запускаю этот код, я получаю следующую ошибку относительно метода рендеринга в компоненте Records:

Uncaught TypeError: Невозможно прочитать свойство 'map' из неопределенного

Я прошу прощения за длину этого вопроса, но я работал над ним некоторое время, и я откровенно сбит с толку.

У кого-нибудь есть идея, почему это не работает? Я полностью ценю любой совет, который может дать любой. Спасибо!

2 ответа

this.records.map не определено, потому что записи не определены, не возвращаются как экземпляр var из контроллера после создания экземпляра как @records.

Была такая же проблема с app/views/dashboard/show.html.erb, которая выглядела так:

<%= react_component 'Dashboard', { flashes: flash, user: user}, :div %>

поменял на это для починки под реагирующими рельсами, для меня:

<%= react_component 'Dashboard', { flashes: flash, user: @user}, :div %>

в моем случае переменная экземпляра была названа @user...

Чтобы передать данные из вашего бэкэнда rails для реакции, вы можете использовать jbuilder и передать файл при рендеринге вашего компонента:

<%= react_component "RecordForm",
    render(template: 'records/form.json.jbuilder') %>

Теперь вы должны создать form.json.jbuilder файл в вашем views/records папка:

 json.records do
   json.array! @records do |record|
     json.partial! "record", record: record
   end
 end

Это всего лишь пример, так как я не знаю, как структурированы ваши данные, но это хороший способ сделать это. Чтобы узнать больше об этом: https://github.com/rails/jbuilder

Для отправки данных из React в Rails вы должны использовать ajax-вызовы, инициируемые событиями.

Другие вопросы по тегам