Quick intro to React...
Contents:
Objectives:
- Explain what React is and how it compares to Angular
- Set up a modern React environment with Babel and Webpack
- Create and render a React component in the browser
YOU: What is React? How does it compare to Angular?
Create a new project directory:
$ mkdir react-intro
$ cd react-intro
$ npm init -y
Install gulp and babel:
$ npm install --save-dev [email protected] [email protected] [email protected]
YOU: What's babel? What does
babel-preset-latest
do?
Then add the following to package.json:
"babel": {
"presets": [
"latest"
]
}
Create a gulpfile.js in the project root:
const gulp = require('gulp');
const babel = require('gulp-babel');
gulp.task('build', () =>
gulp.src(['src/**/*.js'])
.pipe(babel())
.pipe(gulp.dest('lib'))
);
Now add a "src" and "lib" folder, and then add an index.js file to the "src" to test babel:
console.log('hello, world!');
Finally, add a start
script to package.json:
"scripts": {
"start": "gulp build && node lib/index.js"
},
Sanity Check:
npm start
> [email protected] start /react-intro
> gulp build && node lib/index.js
[10:46:26] Using gulpfile ~/react-intro/gulpfile.js
[10:46:26] Starting 'build'...
[10:46:26] Finished 'build' after 615 ms
hello, world!
You: What happened?
Install:
$ npm install --save-dev [email protected] [email protected]
$ npm install --save-dev [email protected] [email protected]
$ npm install --save-dev [email protected] [email protected]
You: Why lint? What do those packages do?
Add the config to package.json:
"eslintConfig": {
"extends": "airbnb",
"plugins": [
"import"
]
},
Update gulpfile.js with a new task:
gulp.task('lint', () =>
gulp.src([
'gulpfile.js',
'src/**/*.js',
])
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError())
);
Make sure to add the dependency:
const eslint = require('gulp-eslint');
Then add the lint
task to the build
:
gulp.task('build', ['lint'], () =>
gulp.src(['src/**/*.js'])
.pipe(babel())
.pipe(gulp.dest('lib'))
);
Run the linter:
$ npm start
You should see a warning:
/react-intro/src/index.js
1:1 warning Unexpected console statement no-console
โ 1 problem (0 errors, 1 warning)
Ignore it.
You: Why are we ignoring it?
Within "src" add a new file called cats.js:
class Cat {
constructor(name) {
this.name = name;
}
meow() {
return `Meow meow, I am ${this.name}`;
}
}
module.exports = Cat;
Update index.js:
const Cat = require('./cats');
const toby = new Cat('Toby');
console.log(toby.meow());
Run npm start
:
Meow meow, I am Toby
You: What's happening here?
Install:
npm install --save [email protected] [email protected]
You: What's react dom?
Then add a "dist" folder with an index.html file:
<!doctype html>
<html>
<head>
<title>React Intro</title>
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>
What's bundle.js?
Add a div
to the index.html:
<div class="app"></div>
Create a new file in "src" called client.jsx:
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
import Cat from './cats';
const catMeow = new Cat('Browser Cat').meow();
const App = props => (
<div>
The cat says: {props.message}
</div>
);
App.propTypes = {
message: PropTypes.string.isRequired,
};
ReactDOM.render(<App message={catMeow} />, document.querySelector('.app'));
You: Is that HTML in a JS file? Why? What's JSX? Also, what does babel-preset-react do?
To process the .jsx file, install:
$ npm install --save-dev [email protected]
Update the babel
field in package.json:
"babel": {
"presets": [
"latest",
"react"
]
},
Finally, update the lint
task to handle .jsx files:
gulp.task('lint', () =>
gulp.src([
'src/**/*.js',
'src/**/*.jsx',
])
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError())
);
Run the linter:
$ gulp lint
You should see the following error:
/react-intro/src/client.jsx
17:44 error 'document' is not defined no-undef
You: Why did we get this error?
To correct this, update the eslintConfig
in package.json:
"eslintConfig": {
"extends": "airbnb",
"plugins": [
"import"
],
"env": {
"browser": true
}
},
Install:
$ npm install --save-dev [email protected] [email protected]
You: What's webpack? What does babel-loader do? Why all these damn tools?!?!
Then add webpack.config.js to the project root:
module.exports = {
entry: './src/client.jsx',
output: {
path: './dist',
filename: 'bundle.js',
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
},
],
},
resolve: {
extensions: ['', '.js', '.jsx'],
},
};
Update the start
script to package.json:
"start": "gulp lint && webpack"
Run:
$ npm start
Then open the index.html file within "dist" in your browser. You should see:
The cat says: Meow meow, I am Browser Cat