Компонент не отображается

Я новичок, чтобы реагировать, и я пытаюсь что-то построить, чтобы изучить его концепции.

Я создал несколько компонентов реакции, но не могу понять, почему мой компонент Post не отображается после успешного выполнения запроса JSON.

примечание: компоненты Posts и PostList рендерятся без проблем.

Что мне здесь не хватает?

/** @jsx React.DOM */
var Posts = React.createClass({
  render: function() {
    return (
      <div className="posts">
        <h3>Featured Jobs</h3>
        <PostList />
        <p>More Awesome Jobs →</p>
      </div>
    )
  }
});

var PostList = React.createClass({
  getInitialState: function() {
    return { posts: [
    ] };
  },

  componentDidMount: function() {
    $.getJSON('/api/posts', function(results) {
      this.setState({
        posts: results
      });
    }.bind(this));
  },

  render: function() {
    var posts = this.state.posts.map(function(post) {
      return <PostListItem post={post} />;
    });

    return <ul className='post-list'>{posts}</ul>;
  }
});

var PostListItem = React.createClass({
  handleClick: function(e) {
    var post_id = this.props.post.id;
    var path = '/api/posts/' + post_id;
    $.getJSON(path, function(post) {
      return <Post title={post.title} location={post.location} description={post.description} />;
    });
  },

  render: function() {
    return (
      <div className="post-item">
        <li key={this.props.post.id}><a href="#" onClick={this.handleClick}>{this.props.post.title}</a></li>
      </div>
    );
  }
});

var Post = React.createClass({
  render: function() {
    return(
      <div className="post">
        <h1>{this.props.title}</h1>
        <h2>{this.props.location}</h2>
        <p>{this.props.description}</p>
      </div>
      );
  }
});

ps: я визуализирую компонент Posts через хелпер rails, но вы можете предположить, что он работает нормально.

Заранее спасибо :)


person Kleber S.    schedule 21.06.2014    source источник
comment
Вы визуализируете DIV внутри UL. Кроме того, что может произойти при возврате компонента Post в функции обратного вызова $.getJSON?   -  person David Hellsing    schedule 22.06.2014
comment
@David Спасибо за ваш ответ. Я хотел бы отобразить компонент Post поверх компонента Posts. Другими словами, чтобы избежать перенаправления на страницу сведений о публикации.   -  person Kleber S.    schedule 22.06.2014


Ответы (2)


Вам нужно будет найти способ передать данные Post в обратном вызове ajax (возврат компонента ничего не даст). Один из способов — использовать setProps, например:

$.getJSON(path, function(post) {
  Post.setProps(post);
});

Обратите внимание, что это можно сделать только для компонентов корневого уровня (как указано в документации). Возможно, вам нужно найти более общий способ обработки реактивных данных (магистраль и т. д.).

person David Hellsing    schedule 21.06.2014
comment
Еще раз спасибо. Получил работу callind renderComponent с setProps, как вы предложили. - person Kleber S.; 22.06.2014
comment
Не используйте здесь renderComponent. Это очень анти-React. Я опишу свое предложение в реальном ответе. - person Paul O'Shannessy; 28.06.2014

Я бы настоятельно предложил не вызывать renderComponent внутри компонента, как вы сказали в другом ответе. Если я совершенно неправильно понял, что вы делаете, пожалуйста, проигнорируйте меня.

Я предполагаю, что у вас есть что-то вроде этого в PostListItem:

// handleClick()
$.getJSON(path, function(post) {
  React.renderComponent(Post(post), this.getDOMNode());
});

Таким образом вы запутаете React, и если когда-нибудь выйдет обновление, вы потеряете этот пост.

Вместо этого оставьте весь рендеринг вашей функции render и поместите туда логику ветвления.

// handleClick()
$.getJSON(path, function(post) {
  this.setState({post: post})
}.bind(this));

// render()
// probably want to have getInitialState return {post: null}
if (this.state.post) {
  return <Post data={this.state.post}/>;
} else {
  // return fallback thing
}

Помните, что render должно описывать, как выглядит ваш компонент в любой момент времени. Как только вы вырветесь из этого и начнете модифицировать DOM в других частях вашего приложения/компонента, у вас почти наверняка появятся ошибки.

person Paul O'Shannessy    schedule 28.06.2014
comment
привет @paul-oshannessy, спасибо за ваш ответ, я, вероятно, делаю это неправильно, как вы сказали, но я не знаю, как отобразить компонент где-то, у которого уже есть другой контент. Я хотел бы перезаписать его этим новым контентом (исходящим из ajax). Что-то вроде размонтирования «неиспользуемого» компонента и рендеринга этого нового. Как мне это сделать? - person Kleber S.; 30.06.2014
comment
Вы не размонтируете и не визуализируете новый, вы просто описываете в render, как должно выглядеть ваше представление на основе данных. Если он должен выглядеть иначе, setState, в свою очередь, вызовет render, и ваше представление будет обновлено. - person Paul O'Shannessy; 01.07.2014
comment
@ paul-oshannessy Чего я просто не понимаю, так это потока сборки приложения с помощью React. Я имею в виду, я получил ваш ответ, но таким образом компонент Post отображается внутри компонента PostList, что не входит в мои намерения. - person Kleber S.; 03.07.2014
comment
Возможно, вы могли бы лучше описать, что вы на самом деле хотите, чтобы ваше намерение было. - person Paul O'Shannessy; 03.07.2014
comment
Конечно! Я создал суть с полным кодом для этого компонента с намерением сделать комментарий. Спасибо за помощь мне в этом :) - person Kleber S.; 03.07.2014
comment
Ах. Да, вы, вероятно, хотите какой-то маршрутизатор. Вы, вероятно, также захотите переместить выборку и хранение данных из этих компонентов в более высокую точку в своем приложении. т.е., если PostListItem извлекает полные данные для сообщения, он владеет данными, и только его дочерние элементы могут их использовать. Но если у вас есть PostDataStore (не компонент), который обрабатывает всю выборку и хранение данных, вы можете получить к нему доступ откуда угодно и изменить рендеринг верхнего уровня (что происходит с маршрутизаторами). - person Paul O'Shannessy; 03.07.2014