React & Flux In ES6! (Pt 1/2)
I began learning react and flux a short time ago. As I searched the web for react, webpack, and flux, written in ES6, I failed to find a tutorial that had what I truly wanted. A tutorial I could run through start to finish that required minimal effort and met my search criteria.
I was able to string together the bits to form my ideal tutorial. A project that’s familiar, easily configurable, concise, and most importantly… IN ES6!
Overview
Prerequisites:
- Knowledge of React
- Knowledge of JS
- NPM installed
With this tutorial I aim to teach you:
- how to write a react to-do list project in ES6
- how to configure webpack
- an understanding of flux architecture
- how to implement the necessary Flux architecture for this project
Pt 1 completed project here: Todo-Tutorial
Introduction
Initializing NPM and the project
Getting things started, we need to initialize a new node project. Open up a shell and navigate to your project’s working directory. Enter command:
$ npm init
Npm will now create a package.json file in our current directory. This file will contain all our dependencies for the project. Npm will ask you a few questions related to the project. You can skip these by pressing enter if you’d like.
Let’s create our folder structure:
Here’s the structure we are aiming to create:
|____js | |____actions | |____components | |____constants | |____dispatcher | |____stores |____package.json
To create the above folder structure, enter command:
$ mkdir js js/actions js/components js/constants js/dispatcher js/stores
Our project’s folder structure has been created, we’ve initialized our node project, we’re ready to go.
Dependencies
For this project, we’ll have several dependencies.
Completed dependencies here: package.json If using this file, to download all dependencies enter: $ npm install
In the root of your projects directory we need to have npm install our dependencies, to do so enter this command:
$ npm install --save react react-dom $ npm install --save-dev react-hot-loader babel-loader flux webpack webpack-dev-server
Our project now has a basic skeleton. Let’s begin to flesh out our server.
Webpack
“Webpack is a module bundler.
Webpack takes modules with dependencies and generates static assets representing those modules.”
– Webpack (webpack.github.io)
Let’s create our webpack configuration file in our project’s root directory:
$ touch webpack.config.babel.js
It is important to include the .babel.js extension so our webpack configuration can be written in ES6:
import path from 'path' export default { entry:['./js/app.js', ], output: { filename: 'bundle.js', path: path.join(__dirname, 'build'), publicPath: 'http://localhost:8080/', }, module: { loaders: [{ test: /\.js$/, exclude: /node_modules/, loaders: ['react-hot', 'babel'], }], }, }
(If you’d like to change the names of your files, paths that can be changed appear in bold)
Making sense of the configuration file
Entry: Entry denotes where our application will be started from. In this case, we are pointing to a file called app.js.
Output: With our output object, we specify to webpack the filename and path for where we would like to create our compiled project. This will create a file called bundle.js in the ./build folder. publicPath refers to the path needed for webpack-dev-server.
Loaders: Loaders pre-process files. In our case, we’d like to pre-process any files that end in .js with the babel loader, excluding any in the node_modules folder. Our other loader is react-hot which allows us to update our modules without requiring a page reload. React-hot saves a lot of time and is a nice addition to the project. ‘react-hot’ must be on the left of babel. Babel reads loaders right-to-left and we need to pass babel’s output into react-hot.
If you would like to read more about webpack configuration, see the link here:
https://github.com/webpack/docs/wiki/configuration
Final Webpack steps:
To confirm our configuration file is working, we need to create a file called app.js:
$ touch ./js/app.js
For simplicity and ease of results, let’s add a console logging statement. Add this to app.js:
console.log(‘Webpack is configured properly.’)
Now let’s create an html file called index.html:
touch ./index.html
We need to load our script with our html so we can see our results:
<!DOCTYPE html> <html>
<body> <script src="bundle.js"></script> </body>
</html>
Our final step is to configure npm to build with the proper configuration. Edit your package.json:
{ “name”: “Todo_tutorial”, “version”: “1.0.0”, “description”: “”, “main”: “index.js”, “scripts”: { “test”: “echo \”Error: no test specified\” && exit 1", “build”: “webpack --colors --progress”, “start”: “webpack-dev-server --hot --inline --color --progress ” }, “author”: “”, “license”: “ISC”, “dependencies”: { “react”: “^0.14.0” }, “devDependencies”: { “babel-core”: “^5.8.25”, “babel-loader”: “^5.3.2”, “flux”: “^2.1.1”, “webpack”: “^1.12.2”, “webpack-dev-server”: “^1.12.0” } }
We’ve added two options to our script for npm to run. Our first option, We want to setup webpack to build our project. Our second option start uses webpack-dev-server to build our project.
Webpack-dev-server is an express server that serves our webpack bundle. It uses Socket.IO to watch the client’s compilation state and respond to changes.
We’re configured! Hopefully. Time to build our project:
$ npm run start
Running this command will start our server. Visit http://localhost:8080. Open the console and we should see this.
Our project is now configured and ready for us to begin using react and flux.
Complete code up to this step can be found here:
ConfigurationAndHtmlComplete
React Components
In the following section, we will build out our react components. For a to-do list, there is two major components. These are a text-input field and a table that displays the current to-do’s.
For the scope of this tutorial, I will only be focusing on using flux to create and view the to-do’s.
For all of our components, we will need to import the react module.
Creating our input field
To create our input field, we need to create a component in our js/components folder. (including .react is not necessary)
$ touch js/components/TodoTextInput.react.js
Assuming you are familiar with react, there is not significant change from ES5 -> ES6. Here is our code for our textInputField:
This component takes in placeholder and a callback onSave that is executed when we press Enter.
Creating our header
We will use our header to pass in our callback to TodoTextInput. Create a file called Header.react.js in our components folder.
touch ./js/components/Header.react.js
We now need to include this component in our app.js file:
Finally, let’s update our index.html to include a place to put this component.
<!DOCTYPE html> <html>
<body> <div id=”todo-input”></div> <script src=”bundle.js”></script> </body>
</html>
Open console and enter a todo item. You should see a console output similar to this image:
Key changes in ES6
With ES6, we can now extend components to create our classes. Say goodbye to React.createClass({ ….}). Additionally, we no longer use getInitialState() to load our state and prop type variables. We can now use a method called constructor to create our object.
The most important change
React.createClass({}) by default bound our methods to our class. In ES6, this is no longer provided. We now need to bind our components to explicitly. This can be done in multiple ways. I will demonstrate two different ways in this tutorial. For this class, we explicitly bound our methods where they are used, see line 41. This can also be done in the constructor which I will demonstrate later.
Complete code up to this point can be found here:
TodoComponent_complete
In the next part, We’ll cover:
- flux architecture
- how to implement our create action in flux
- adding the final touches to complete the project
Comments, questions, lost?
Thanks for following along. I hope you found this tutorial useful. Stay tuned for part 2 coming soon!
I’d love to hear your thoughts on this tutorial. Leave a comment, recommend, suggestions, or send me a tweet!
Special thanks to the tutorials that I’ve pieced together:
https://github.com/gaearon/react-hot-boilerplate
https://facebook.github.io/flux/docs/todo-list.html
http://jslog.com/2014/10/02/react-with-webpack-part-1/
and the others I’m sure I’ve left out.