There are two ways to add and remove atmosphere packages in Meteor: directly add it in .meteor/packages or use the meteor add or meteor remove commands.
We will remove blaze and jquery for this example:
>> meteor remove blaze-html-templates
This will result in the following terminal:
blaze-html-templates removed from your project
caching-compiler removed from your project
caching-html-compiler removed from your project
templating removed from your project
templating-compiler removed from your project
templating-runtime removed from your project
templating-tools removed from your project
Now if you run your app, you will note that nothing is loaded. You'll need to install the html-static package to let Meteor load a static HTML file.
You can install it with the following command:
>> meteor add static-html
It will add all the needed dependencies:
caching-compiler added, version 1.1.8
caching-html-compiler added, version 1.0.7
static-html added, version 1.1.13
templating-tools added, version 1.0.5
Remove Jquery by deleting it in the package file (.meteor/packages)
jquery@1.11.10 # Helpful client-side library
You can add and remove packages even if the server is running. Meteor will restart it automatically when a package is removed or added.
The next step is directories and files:
- Create index.js in the root of the client folder. This will be our start up file where we can import and render the rest of the components.
- Create the components folder. For a small demo app like this, we can keep the components in a folder components.
- In folder components, create a Timer.js file, you can use and also Timer.jsx; Meteor will transpile JSX into JavaScript by default. Both ways are fine.
Install react and react-dom with npm:
>> npm install react --save
>> npm install react-dom --save
In the Timer.js file, let's define our component:
import React from 'react';
import ReactDOM from 'react-dom';
class Timer extends React.Component {
constructor(props) {
super(props);
}
render() {
return (<div>
<p>Timer</p>
</div> )
}
}
export default Timer;
It is a class component that will display the time pushed in real time from the server. The only difference between preceding examples and this one, is that we exported that component to use it in other components.
Now, let's import and render it in the index.js file:
import React from 'react';
import {render} from 'react-dom';
import Timer from './components/Timer'
render(<Timer/>, document.getElementById('root'))
First, let's create the functionality of the app on the client; then we can start pushing the data from the server.
Initialize the state in the constructor and set a new state every second:
constructor(props) {
super(props);
this.state = {time: 0};
}
componentDidMount() {
setInterval(() => this.setState({time: new Date().toLocaleString()}), 1000);
}
Also, we have the following code in the render() method:
render() {
return (<div>Time :
{this.state.time}</div>)
}
When the component mounts, we set a new state every second. This will force the component to re-render and display the latest state.
To exercise the idea of the state and the props, we can now create a child component that the Timer component will render and pass its state as prop.
Create a child component in the components folder, called TimerDisplay:
class TimerDisplay
extends React.Component {
constructor(props) {
super(props);
}
render() {
return
(
<div>Time : {this.props.time}</div>
)
}
}
export default TimerDisplay;
The TimerDisplay will receive and render the data through the props.time. It can be a stateless presentational component, and it can be defined as a function instead of a class:
import TimerDisplay from './TimerDisplay';
class Timer extends React.Component {
constructor() {
super();
this.state = {time: new Date().toLocaleString()};
}
componentDidMount() {
setInterval(() => this.setState({time: new Date().toLocaleString()}), 1000);
}
render()
{
return (
<div>
<TimerDisplay time={this.state.time}/>
</div>)
}
}
export default Timer;
Here, the parent component, Timer, re-renders every time its state changes, and then renders the child component, TimerDisplay, by passing its state as props.
What will happen if we add another TimerDisplay, but this time with a static value:
render()
{
return (
<div>
<TimerDisplay time={this.state.time}/>
<TimerDisplay time='today'/>
</div>)
}
To see the power of React in action, open the console in Chrome and press the Esc key then go to Rendering and click on the checkbox Paint Flashing. You will note that even if we rendered both TimerDisplay, only the one that has its value changed is re-rendering.