React Hot Loader – With Stateless components (webpack) [Code Example]

React Hot Loader – With Stateless components (webpack) [Code Example]

Reading Time: 2 minutes

Everybody knows React or at least heard of it, if not it is never too late. I saw a great tutorial by Robin Wieruch The SoundCloud Client in React + Redux which takes you, step by step, making a cool SoundCloud app from scratch. You need some basic knowledge if you want to follow the tutorial, but is it really basic stuff you can get in the video tutorials around the web.

check out the code on github

The issue I faced was with step 6: “First React Component” where you want the react-hot-loader automatically refresh the changes you make on your files. RHL is not compatible yet with stateless functions components so the recommendations around the web was to use the beta of version 3 which gives you some boilerplate, I struggled to get it work but finally managed to get the configuration to make it work as expected.

What did I do:

package.json

{
  "name": "favesound-project",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --progress --colors --hot --config ./webpack.config.js"
  },
  "devDependencies": {
    "babel-core": "^6.0.20",
    "babel-loader": "^6.0.1",
    "babel-preset-es2015": "^6.0.15",
    "babel-preset-react": "^6.0.15",
    "babel-preset-stage-0": "^6.0.15",
    "chai": "^3.5.0",
    "enzyme": "^2.3.0",
    "exports-loader": "^0.6.3",
    "imports-loader": "^0.6.5",
    "jsdom": "^9.2.1",
    "mocha": "^2.5.3",
    "react-addons-test-utils": "^15.1.0",
    "react-hot-loader": "^3.0.0-beta.0",
    "webpack": "^1.12.2",
    "webpack-dev-server": "^1.12.1"
  },
  "dependencies": {
    "react": "^15.1.0",
    "react-dom": "^15.1.0",
    "react-redux": "^4.4.5",
    "react-router": "^2.4.1",
    "react-router-redux": "^4.0.5",
    "redux": "^3.5.2",
    "redux-logger": "^2.6.1",
    "redux-thunk": "^2.1.0",
    "soundcloud": "^3.1.2",
    "whatwg-fetch": "^1.0.0"
  },
  "author": "",
  "license": "ISC",
  "keywords": [],
  "description": ""
}

 

webpack.config.js

<pre class="javascript">const webpack = require('webpack');
&nbsp;
module.exports = {
    entry: [
        'react-hot-loader/patch',
        'webpack-dev-server/client?http://localhost:8080',
        'webpack/hot/only-dev-server',
        './src/index.js'
    ],
    module: {
        loaders: [{
            test: /\.jsx?$/,
            exclude: /node_modules/,
            loaders: ['babel']
        }]
    },
    resolve: {
        extensions: ['', '.js', '.jsx']
    },
    output: {
        path: __dirname + '/dist',
        publicPath: '/',
        filename: 'bundle.js'
    },
    devServer: {
        contentBase: './dist',
        hot: true
    }
};</pre>

.babelrc

<pre class="json">{
  "presets": ["es2015", "stage-0", "react"],
  "plugins": ["react-hot-loader/babel"]
}</pre>

index.js – the app should be surrounded by the AppContainer element

<pre>import { AppContainer } from 'react-hot-loader'; // required
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

const rootEl = document.getElementById('app');

ReactDOM.render(
 &lt;AppContainer&gt;
 &lt;App /&gt;
 &lt;/AppContainer&gt;,
 rootEl
);

if (module.hot) {
 module.hot.accept('./App', () =&gt; {

 const NextApp = require('./App').default;

 ReactDOM.render(
 &lt;AppContainer&gt;
 &lt;NextApp /&gt;
 &lt;/AppContainer&gt;,
 rootEl
 );
 });
}

App.js

<pre>import React, { Component } from 'react';
import Stream from './components/Stream';

const tracks = [
 {
 title: 'Some track 11'
 },
 {
 title: 'Some other track 22'
 }
];

export default class App extends Component {
 render() {
 return (
 <div>
 <Stream tracks={tracks}/>
 </div>
 );
 }
}</pre>

and last file is the component that represented by stateless function Stream.js

<pre>import React from 'react';

function Stream({ tracks = [] }) {
 return (
 <div>
 {
 tracks.map((track, key) => {
 return <div className="track" key={key}>{track.title}</div>;
 })
 }
 </div>
 );
}

export default Stream;</pre>

You can find the full code example in my github project, just clone it and “npm install” it :).