【问题标题】:Render single document in React with Meteor在 React 中使用 Meteor 渲染单个文档
【发布时间】:2016-10-26 12:42:42
【问题描述】:

为了呈现文档列表,我在从订阅返回数组的函数上使用.map()

{this.getApplications().map( (application) => {
  return application.name;
})}

但是当我想像这样渲染单个文档时:

export default class ApplicationForm extends TrackerReact(React.Component) {

  constructor() {
    super();
    this.state = {
        subscription: {
            applications: Meteor.subscribe('applications')
        }
    }
  }

  componentWillUnmount() {
    this.state.subscription.applications.stop();
  }

  getSingleApplication() {

    const applicationDoc = Applications.find().fetch();

    if (applicationDoc) {
        return applicationDoc[0];
    }
  }

  render () {

    const name = this.getSingleApplication().name;

    return (
        <div>
            {name}
        </div>
    );
  }
}

我收到以下错误:

无法读取未定义的属性“名称”

我想我错过了一些基本的 javascript。

或者它可能与页面加载时未准备好订阅有关?

【问题讨论】:

  • 我们能看到更多代码吗?
  • this.getSingleApplication() 返回未定义。我们无能为力。
  • Cannot read property 'name' of undefined - 表示你需要学习 javascript...getSingleApplication 返回 undefined...
  • @KellyJAndrews this.getSingleApplication() 在订阅准备好之前返回 undefined,当订阅准备好时返回文档。
  • 不知道 - 但这似乎很有用 - discovermeteor.com/blog/data-loading-react

标签: javascript reactjs meteor


【解决方案1】:

首先,当您要查找单个文档时,使用.findOne()。这将返回一个对象而不是光标,因此您不需要 .fetch().map()

getSingleApplication() {
  return Applications.findOne(); 
}

然后,您需要进行防御性编码,以防万一找不到(例如,如果您的订阅尚未准备好,则可能发生这种情况)。

render () {

  const app = this.getSingleApplication();
  const name = app && app.name;

  if (name) { // assuming you don't want to render anything if there is no name
    return (
      <div>
        {app.name}
      </div>
    );
  }
}

【讨论】:

  • 感谢您的澄清!该文档将包含许多属性,我需要为每个属性添加一个 if 语句吗?
  • 视情况而定。所有的属性会一直在一起,还是可以任意组合出现?如果他们总是在一起,那么就做if(app)
【解决方案2】:

免责声明:我从未使用过 Meteor,也没有经过测试。

您需要有某种方式来对您的订阅“准备就绪”做出反应,如果我对文档的理解正确,您可以通过在订阅时传递一个回调函数来做到这一点。

所以你需要

constructor() {
    super();
    this.state = {
        ready: false,
        subscription: {
            applications: Meteor.subscribe('applications', () => this.setState({ready: true})
        }
    }
  }

在渲染中:

render () {
    if (!this.state.ready) return null;
    const name = this.getSingleApplication().name;

    return (
        <div>
            {name}
        </div>
    );
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 2017-10-31
    • 1970-01-01
    相关资源
    最近更新 更多