Whew. I feel like this has been wasting precious time I could be making progress on my app, but it’s also important, I think, for me to figure out this inter-component communication thing, come up with something that works (even if it’s not perfect). I appreciate all the input and ideas!
@SkinnyGeek1010, I like the idea of using ReactiveDict
. So this is what I’ve got going on for this spinner component of mine. This version was just a rough test I threw together to see if it works. The spinner has a 1.5s delay before it shows up, so that it only displays if an operation is taking longer than expected (I personally don’t like seeing an overlay and spinner pop up for operations that take less than a second).
app-state.js
appState = new ReactiveDict('appState');
appState.set({
spinnerVisible: false,
spinnerMessage: ''
// other global states here, for other components
});
Actions = {
showSpinner(message) {
appState.set({
spinnerVisible: true,
spinnerMessage: message
})
},
hideSpinner() {
appState.set({spinnerVisible: false});
}
};
Spinner.jsx
Spinner = React.createClass({
displayName: 'Spinner',
mixins: [ReactMeteorData],
getMeteorData() {
return {
message: appState.get('spinnerMessage'),
}
},
getInitialState() {
return {
visible: false
}
},
render() {
if (!this.state.visible) {
return false;
}
return (
<div>
[graphical spinner here] ({this.data.message})
</div>
)
},
componentDidMount() {
this.timer = setTimeout(() => {
this.setState({visible: true});
}, 1500);
}
});
Home.jsx
Home = React.createClass({
displayName: 'Home',
mixins: [ReactMeteorData],
getMeteorData() {
return {
spinnerVisible: appState.get('spinnerVisible')
}
},
render() {
return (
<div>
<DummyWrapper />
{this.data.spinnerVisible ? <Spinner /> : ''}
</div>
)
}
});
So, anywhere in the app, if an operation could potentially take some time:
handleClick() {
Actions.showSpinner('loading all the things!');
Meteor.call('potentiallyLongOperation', function () {
Actions.hideSpinner();
});
},
The spinner waits 1.5s, then displays, and then is unmounted when Actions.hideSpinner()
is called.
As you mentioned, Adam, the one caveat (but not necessarily a bad thing) is that you’re pretty tied to using the ReactMeteorData
mixin on every component that needs to access the app state. As you can see, I’ve opted to not pass props simply because I don’t want to have to deal with that on a larger scale.
The only other slight issue is that if I were to use these spinner calls within a getMeteorData
, then getMeteorData
is fired off four times: once when the component mounts, another time when I call Actions.showSpinner
(because it changes the reactive dict), another time when the sub is ready, and another time when Actions.hideSpinner
is called.