【问题标题】:Component not being rendered组件未呈现
【发布时间】:2014-08-12 02:41:56
【问题描述】:

我是新手,我正在尝试构建一些东西来学习它的概念。

我创建了一些 react 组件,但无法弄清楚为什么我的 Post 组件在 JSON 请求成功完成后没有被呈现。

注意:PostsPostList 组件的渲染没有问题。

我在这里错过了什么?

/** @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:我正在通过 rails helper 渲染 Posts 组件,但您可以假设它工作正常。

提前谢谢你:)

【问题讨论】:

  • 您在 UL 中渲染 DIV。另外,在 $.getJSON 回调函数中返回 Post 组件时会发生什么?
  • @David 感谢您的回复。我想在 Posts 组件上渲染 Post 组件。也就是说,避免重定向到帖子详情页面。

标签: reactjs react-jsx


【解决方案1】:

我会强烈建议不要像您所说的那样在组件内调用 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,你几乎肯定会遇到错误。

【讨论】:

  • 嗨@paul-oshannessy,谢谢你的回答,我可能像你说的那样做错了,但我不知道如何在已经有另一个组件的地方渲染一个组件内容。我想用这个新内容(来自 ajax)覆盖它。诸如卸载“未使用”组件并渲染这个新组件之类的东西。我该怎么做?
  • 您不会卸载并渲染一个新的,您只需在render 中根据数据描述您的视图应该是什么样子。如果它看起来不同,setState 将依次调用render 并且您的视图将被更新。
  • @paul-oshannessy 我只是不明白的是使用 React 构建应用程序的变化。我的意思是,我得到了你的答案,但是 Post 组件是在 PostList 组件中呈现的,这不是我的意图。
  • 也许你可以更好地描述你真正想要的意图是什么。
  • 当然!我创建了一个gist,其中包含此组件的完整代码,我的意图是作为评论。谢谢你在这方面的帮助:)
【解决方案2】:

您需要找到一种在 ajax 回调中将数据传递给 Post 的方法(返回组件将无济于事)。一种方法是使用setProps,例如:

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

请注意,这只能对根级组件执行(如文档中所述)。也许您需要找到一种更通用的方式来处理响应式数据(Backbone 等)。

【讨论】:

  • 再次感谢您。让它像你建议的那样使用 setProps 调用 callind renderComponent。
  • 这里不要使用 renderComponent。这是非常反 React 的。我会用真实的答案描述我的建议。
猜你喜欢
  • 2013-06-08
  • 2018-05-30
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 2021-02-27
  • 2020-02-19
  • 2018-01-08
相关资源
最近更新 更多