What is the more natural way to set a tracker that depends on a component state with React? Do I have to create a reactive variable that mimics its behavior or is there a better solution?
thanks that looks good. But it seems that you are focussing on bringing reactivity to what’s happening within render, which is not where one would start a tracker.
That doesn’t work
import React, {Component} from 'react';
import {TrackerReactMixin} from 'meteor/ultimatejs:tracker-react';
import reactMixin from 'react-mixin';
export default class TrackerTest extends Component {
constructor(props) {
super(props);
this.state = {
SomeUIState: false,
}
}
render() {
console.log('from render', this.state.SomeUIState);
return <div></div>
}
componentWillMount() {
const self = this;
Tracker.autorun(() => {
console.log('SomeUIState', self.state.SomeUIState);
});
}
componentDidMount() {
const self = this;
// change the state after some time
setTimeout(() => {
self.setState({'SomeUIState': true})
console.log('UI State has changed to true')
}, 1000);
}
}
reactMixin(TrackerTest.prototype, TrackerReactMixin);
I don’t understand what you try to do here. Just use a reactive data source, no need to use an additional autorun. Also, constructor() and componentWillMount() are exactly the same thing in react ES6. Take a look at the TrackerReact-Example App
What are you trying to do within the Tracker.autorun? If it’s UI-related, just stay on the React side and use state, and render to do the update. If it’s more app- or data-related, stay on the Meteor side and try to use ReactiveVars and getMeteorData.
If the change is coming from outside the component as a result of user action, then you should bring in a Flux store of some sort to power variables in getMeteorData. You could use Tracker in such a case, but I tend not to use Tracker in React. Tracker autoruns can run anywhere at anytime and it’s easy to lose “track” (ha!) of them, resulting in autoruns running when you least expect it and vice-versa.
Good to know for constructor and componentWillMount. thanks.
I’m not using the tracker as a data source, but to start an action when some state is met & some data is available, and to do it only for the first time that this condition is met (so render is not the good place to do that.).
I’ll probably use a mixture of a tracker that’ll react to the data change and of a vanilla callback when the state is changed.
Since state triggers reactivity in React, if would feel natural for it to trigger reactivity in Meteor as well and I was wondering if there’d be something that would react both worlds.
Like render reacts to state change, and Tracker reacts to Meteor’s data change, but there’s not something that react to either.
I am still not sure what you try to do. You can not stuff something arbitrary into tracker and expect it to become reactive. Tracker works with tracker aware libraries; though it is possible to write costum handlers. Read up on it here: https://atmospherejs.com/meteor/tracker
If you try to communicate between react and blaze, you could simply use TrackerReact and use a session variable. That you can change inside react or blaze. https://www.meteor.com/tutorials/blaze/temporary-ui-state
Session.get(“hideCompleted”)
Than
import React, {Component} from 'react';
import {TrackerReactMixin} from 'meteor/ultimatejs:tracker-react';
import reactMixin from 'react-mixin';
export default class TrackerTest extends Component {
constructor(props) {
super(props);
this.state = {
SomeUIState: Session.get("hideCompleted"),
}
}
render() {
console.log('from render', this.state.SomeUIState);
return <div>{Session.get("WelcomeToMeteor")}</div>
}
// (...)
which is ok but duplicates logic and will get more complex when more variables get involved. So I was curious if there’d be a way to combine the UI and Meteor reactivity in one place.
This still doesn’t feel super right to me from a design standpoint because you have two reactive layers that need to be handled separately, and here you duplicate reactive variables and state. It’d be nice to have Meteor & React integrated in a way that you don’t have to think of them as two things, as it is with Blaze.