【问题标题】:Meteor + React - Session Variable not behaving reactivelyMeteor + React - 会话变量没有反应性行为
【发布时间】:2017-06-20 04:49:11
【问题描述】:

我是社区的新手,但我一直在搜索一个星期,看看我的问题是否之前得到了回答,但显然与带有 react 的流星 1.4 相关的并不多。

所以我正在构建一个应用程序(我是 Meteor + React 的新手),它读取存储在服务器上的巨大 XML 文件,然后需要从中提取一些数据,显示它,然后使用它启动一些其他功能在不同页面上获取数据,所以我认为将这个解析为 JSON 对象的 XML 存储到会话变量中是个好主意,但随后问题立即开始,因为第一个简单的数据提取没有反应。

这是代码:

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';

FlightPlan = new Mongo.Collection("flightPlan");

export default class FlightPlanWrapper extends Component { 
  constructor(props) {
    super(props);
  }

  xmlDemo(){
    Meteor.call('xmlDemo',function(error,flightPlanXML){
      let tempXML = flightPlanXML;
      Session.set({
        'flightPlanXML': flightPlanXML
      });
    });
  }

  render() {
    const flightNumber = Session.get('flightPlanXML') ? (
      <span className="flightNumber">{Session.get('flightPlanXML').FlightPlan.FlightInfo.aTCCallsign}</span>
    ) : '';

    return (
      <div id='flightPlan' className='contentWrapper'>
        <h2>
          Flight Plan
        </h2>

        {
          Session.get('flightPlanXML') ? flightNumber :
            <div>
              <button onClick={this.xmlDemo.bind(this)}>click me</button>
            </div>
        }
      </div>
    );
  }
}

export default createContainer (() => {
  Meteor.subscribe('flightPlan');
  return {
    'resolutions': FlightPlan.find().fetch()
  };
}, FlightPlanWrapper);

所以我不确定我对系统的理解是否正确,但我想在这个简化版本的代码中做的是显示按钮或该会话变量的内容。

请注意,当我在单击按钮后更改页面然后返回同一页面时,内容会正确更新。

【问题讨论】:

  • 更新:我试图破坏在一个名为 (FlightPlanContent.jsx) 的文件上输出航班号以及在另一个文件 (FlightPlanForm.jsx) 上输出按钮的代码。
    然后我在 (FlightPlanWrapper.jsx) 中进行调用,以这种方式渲染:{Session.get('flightPlanXML') ? &lt;FlightPlanContent flightData={Session.get('flightPlanXML')}/&gt; : &lt;FlightPlanForm /&gt;} 但结果仍然相同:输出不是反应式的,它仅在我更改页面后才会更改(而不是刷新,因为它会转储会话变量)。

标签: session meteor reactjs


【解决方案1】:

使用 Meteor + React,所有响应式 Meteor 数据源(例如 DB 集合 find 调用和 Session.get)都需要在 createContainer 内。所以你需要这样做:

export default createContainer (() => {
  Meteor.subscribe('flightPlan');
  return {
    'resolutions': FlightPlan.find().fetch(),
    flightPlan: Session.get('flightPlanXML')
  };
}, FlightPlanWrapper);

然后你可以在渲染函数中使用this.props.fightPlan

请注意,如果您的 XML 文件的内容在服务器上发生更改,则这些更改不会反映在 UI 中,这不是反应式的。如果这是您想要的,我建议您在服务器上编写一个脚本,从 XML 中提取数据并将其写入 Mongo 数据库,以便 Meteor 像任何其他数据库数据一样使用。

根据 Cod3Citrus 的要求进行澄清

要了解为什么这是必要的,您必须了解 React 反应性和 Meteor 反应性是两个不同的东西。 React 反应性起作用,因此当且仅当组件的propsstate 发生更改时,其render 函数才会重新运行。 Meteor 反应性的工作原理是,当 反应性数据源,例如 collection.findSession.get,在反应性上下文中调用 改变值时,这个反应性上下文会重新-跑。 Meteor 反应上下文的例子是Tracker.autorun 和传递给createContainer 的数据函数。因此将 Meteor-reactive 数据源 (Session.get) 放在 React-reactive render 函数中将不起作用

【讨论】:

  • 这对我有用。 @Waiski,你能解释一下为什么这是必要的吗?
  • @Cod3Citrus 我用一个小小的说明更新了答案。我希望能解决它:)
猜你喜欢
  • 2017-07-24
  • 1970-01-01
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多