Reputation: 33
I'm new to the community but I kept searching for one week on it to see if my question was answered before but apparently not much is relating to meteor 1.4 with react.
So I'm building an app (I'm new to Meteor + React) that reads a huge XML file stored on the server and then needs to extract some data from it, display it and then launch some other functions with that acquired data on different pages so I thought it was a good idea to store this XML parsed into a JSON Object into a session variable but then immediately the problems started as the first simple data extraction doesn't behave reactively.
This is the code:
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);
So I'm not sure if my understanding of the system is correct at all but what I would like to do in this simplified version of the code is to either display the button or the content of that session variable.
Please note that when I change page after having clicked the button and then I come back to the same page the content is updated properly.
Upvotes: 2
Views: 1838
Reputation: 9680
With Meteor + React, all reactive Meteor data sources (such as DB collection find
calls and Session.get
) need to be within createContainer
. So you need to do this:
export default createContainer (() => {
Meteor.subscribe('flightPlan');
return {
'resolutions': FlightPlan.find().fetch(),
flightPlan: Session.get('flightPlanXML')
};
}, FlightPlanWrapper);
Then you can use this.props.fightPlan
from within the render function.
Note that this is not reactive in the sense that if the content of your XML file changes on the server, the changes are not reflected in the UI. If this is what you want, I would recommend you to write a script on the server that extracts the data from the XML and writes it to the Mongo database for Meteor to use like any other DB data.
Clarification as requested by Cod3Citrus
To understand why this is necessary, you must understand that React reactivity and Meteor reactivity are two different things. React reactivity works so that when, and only when, the props
or state
of a component changes, its render
function is re-run. Meteor reactivity works so that when a reactive data source, such as collection.find
or Session.get
, that is called within a reactive context changes value, this reactive context is re-run. Examples of Meteor reactive contexts are Tracker.autorun
and the data function passed to createContainer
. Thus placing Meteor-reactive data sources (Session.get
) within React-reactive render
function will not work.
Upvotes: 10