In this article I would be creating an app using a JavaScript library called ReactJS that would connect to the Laravel API endpoint that was created in my previous article. Part one of this article would center more on the app setup and configuration.

STEP 1

Run composer install,

$ composer install

to install all the laravel vendor packages into the project folder. Thereafter change the default content of the package.json.

{
"name": "my-blog-reactapp",
"version": "0.0.0",
"description": "",
"main": "webpack.config.js",
"dependencies": {
"axios": "^0.15.2",
"babel-core": "^6.17.0",
"babel-loader": "^6.2.0",
"babel-plugin-add-module-exports": "^0.1.2",
"babel-plugin-react-html-attrs": "^2.0.0",
"babel-plugin-transform-class-properties": "^6.3.13",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"babel-preset-stage-0": "^6.3.13",
"flux": "^3.1.0",
"history": "^4.4.0",
"react": "^15.0.2",
"react-dom": "^15.3.2",
"react-router": "^3.0.0",
"redux": "^3.6.0",
"redux-thunk": "^2.1.0",
"webpack": "^1.12.9",
"webpack-dev-server": "^1.16.2"
},
"devDependencies": {
"font-awesome": "^4.7.0"
},
"scripts": {
"dev": "webpack-dev-server",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Adelekan David",
"license": "ISC"
}

Then from the terminal run

$ npm install

to download the dependencies needed for the project into a folder called node_modules. Take note that npm is a package manager that comes with Node.js, therefore Node.js has to be installed to make use of npm. You can go to https://nodejs.org/ to download Node.js. Also create a webpack.config.js file in the root folder

var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var path = require('path');
module.exports = {
context: path.join(__dirname, "public"),
devtool: debug ? "inline-sourcemap" : null,
entry: "./js/app.js",
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-0'],
plugins: ['react-html-attrs', 'transform-decorators-legacy', 'transform-class-properties'],
}
}
]
},
output: {
path: __dirname + "/public/js/",
filename: "bundle.js"
},
plugins: debug ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
],
};

Webpack is a module bundler that packs all our source code within the public/js/ folder into one single file “bundle.js” which would be referenced from our laravel blade view.

Step 2

From the routes/web.php, there would be need for just one route which would point to the index view.

<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| This file is where you may define all of the routes that are handled
| by your application. Just tell Laravel the URIs it should respond
| to using a Closure or controller method. Build something great!
|
*/
Route::get('/', function () {
return view('index');
});

This index.blade.php view file would serve as a container for the whole project view.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>My React Blog App</title>
<!-- Bootstrap Core CSS -->
<link href="https://bootswatch.com/cosmo/bootstrap.css" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<script src="{{url('')}}/js/bundle.js"></script>
</body>
</html>

The div container <div id=”app”></div> is the actual wrapper for our react components.

Also create a JavaScript file under public/js/ folder called app.js,

import React from "react";
import ReactDOM from "react-dom";
import {Router, Route, IndexRoute, browserHistory} from "react-router";
import Layout from "./components/Layout";
import Home from "./components/Home";
import Users from "./components/Users";
import Articles from "./components/Articles";
const app = document.getElementById('app');
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={Layout}>
<IndexRoute component={Home}></IndexRoute>
<Route path="users" component={Users}></Route>
<Route path="articles" component={Articles}></Route>
</Route>
</Router>,
app);

The first three lines are import statements for importing the react packages we would be using in this file.

Then we import the Layout component from public/js/components/Layout.js

import React from "react";
import { Link } from "react-router";
import Navigation from "../components/includes/Navigation";
export default class Layout extends React.Component{
render(){
const { location } = this.props;
const containerStyle = {
marginTop: "60px"
};
return(
<div>
<Navigation location={location} />
<div class="container" style={containerStyle}>
<div class="row">
<div class="col-lg-12">
{this.props.children}
</div>
</div>
</div>
</div>
);
}
}

Step 3

Then we create the Navigation component from public/js/components/includes/Navigation.js

import React from "react";
import { IndexLink, Link } from "react-router";
export default class Navigation extends React.Component{
constructor(){
super();
this.state = {
collapsed: true,
};
}
toggleCollapse(){
const collapsed =!this.state.collapsed;
this.setState({collapsed});
}
render(){
const { location } = this.props;
const {collapsed } = this.state;
const homeClass = location.pathname === '/' ? "active" : "";
const usersClass = location.pathname.match(/^\/users/) ? "active" : "";
const articlesClass = location.pathname.match(/^\/articles/) ? "active" : "";
const navClass = collapsed ? "collapse" : "";
return(
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a href="#/" class="navbar-brand">My React App</a>
<button class="navbar-toggle" type="button" onClick={this.toggleCollapse.bind(this)}>
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class={"navbar-collapse " + navClass} id="navbar-main">
<ul class="nav navbar-nav">
<li class={homeClass}>
<IndexLink to="/" onClick={this.toggleCollapse.bind(this)}>Home</IndexLink>
</li>
<li class={usersClass}>
<Link to="users" onClick={this.toggleCollapse.bind(this)}>Users</Link>
</li>
<li class={articlesClass}>
<Link to="articles" onClick={this.toggleCollapse.bind(this)}>Articles</Link>
</li>
</ul>
</div>
</div>
</div>
);
}
}

Also lets create the Home.js, Users.js and Article.js components inside the public/js/components/ folder.

Home.js

import React from 'react';
export default class Home extends React.Component{
render(){
return(
<div>
<h1>Homepage</h1>
</div>
);
}
}

Users.js

import React from 'react';
export default class Users extends React.Component{
render(){
return(
<div>
<h1>Users</h1>
</div>
);
}
}

Articles.js

import React from 'react';
export default class Articles extends React.Component{
render(){
return(
<div>
<h1>Articles</h1>
</div>
);
}
}

Step 4

Finally we run

$ webpack

on the terminal to bundle the js files into the bundle.js single file. Alternatively you can run

$ webpack --watch

This would always watch for changes within the public/js/ folder and then re-bundle the project instead of always running the npm webpack command every single time we make changes to the project.

Then we run

$ php artisan serve

to start the Laravel development server which would be on http://localhost:8000/

Homepage
Users page
Articles page

Conclusion

In the next article we would explore more ReactJS principles including redux, redux-promise, axios etc. Since we already have the api endpoints created using laravel, we would be connecting our app to it. Source code would be available at the end of the series.

If you have any comments, questions or observations, please feel free to drop them in the comment section below.

Thank you.

Comments

comments

Leave a Reply

Your email address will not be published. Required fields are marked *
You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>