Нарушение инварианта в React Render ИЛИ правильный способ итерации и возврата в React

Я сталкиваюсь с постоянными проблемами в своих рендерах React.

Этот код

/** @jsx React.DOM */
var AnswerRows = React.createClass({
  componentDidMount: function() {
  },
  render: function() {
    {this.props.answers.map(function(answer, i) {
      return (
        <div id="answerRow">
          <label className="AnswerText">
            <input type="checkbox" value={answer.id}  />
            {answer.text}
          </label>
        </div>
      );
    }, this)}
  }
});

var QuizTaking = React.createClass({
  componentDidMount: function() {
  },
  render: function() {
    return (
      <div className="card-holder">
        <div className="showQuestionCard x-card host">
          <h3 dangerouslySetInnerHTML={{__html: this.props.question.text}}></h3>
          <div className="answerRows">
            <AnswerRows answers={this.props.question.answers}/>
          </div>
          <div className='submitAnswers'></div>
        </div>
        <div className="paper-shadow-bottom"></div>
      </div>
    )
  }
})

Выдаст мне Invariant Violation: AnswerRows.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object. ошибки. Однако это работает каждый раз:

/** @jsx React.DOM */

var TestIndex = React.createClass({

  propTypes: {
  },
  loadTest: function(i) {
    window.location.replace(this.props.tests[i].url.replace(".json", "/take"))
  },

  render: function () {
    return(
      <div className="testTable card-holder">
        <div className="card-contents">
          {this.props.tests.map(function(test, i) {
            return (
              <div className="testTableRow x-card host" key={test.id}>
                <label className="__TITLE">{test.title}
                  <button onClick={this.loadTest.bind(test, i)}  key={i} type="button" className="StartButton paper-button raisedButton">Start this test</button>
                </label>
                <div className="paper-shadow-bottom"></div>
              </div>
            );
          }, this)}
        </div>
      </div>
    )
  }
});

Я действительно хотел бы понять, что здесь происходит, и, возможно, «правильный» способ сделать это.


person Ryanmt    schedule 17.10.2014    source источник


Ответы (1)


Вы не можете вернуть несколько элементов (например, массив, возвращаемый функцией карты) из функции рендеринга. Кроме того, вам не хватает оператора return. Попробуй это:

var AnswerRows = React.createClass({
  componentDidMount: function() {
  },
  render: function() {
    return (
      <div>
        {this.props.answers.map(function(answer, i) {
          return (
            <div id="answerRow">
              <label className="AnswerText">
                <input type="checkbox" value={answer.id}  />
                {answer.text}
              </label>
            </div>
          );
        }, this)}
      </div>
    );
  }
});
person Becojo    schedule 17.10.2014
comment
Можете ли вы объяснить последнюю строку внутри div? почему это передается на карту? - person monkeyjumps; 11.11.2015
comment
Пожалуйста объясните далее. Я сталкиваюсь с этой точной проблемой и не совсем понимаю решение. - person sweeds; 11.11.2015
comment
@monkeyjumps это делается для того, чтобы значение this внутри функции, передаваемой на карту, совпадало со значением this внутри функции рендеринга. Дополнительные сведения см. в документации карты разработчику .mozilla.org/en-US/docs/Web/JavaScript/Reference/ - person Becojo; 16.11.2015
comment
@sweeds гарантирует, что вы возвращаете ровно один узел в функции рендеринга. Вы не можете вернуть массив из нескольких узлов. Если вы хотите сделать это, вы должны обернуть его в другой элемент, такой как div в решении, которое я дал. - person Becojo; 16.11.2015