Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Frontin' Like
A Back-er
by @frankdejonge
The PHP League
Flysystem
2 million downloads, thank you!
There's no other
option than using
JavaScript.
- most of my friends
JavaScript is a
means to an end.
- almost all of my friends
If JavaScript is
required, I'll hire
somebody.
- my friends who have companies
If we hate something,
why do we do it?
We all like the result:
Snappy UI / UX
I made a server
browser do this!
Loving JavaScript
Hating JavaScript
Dealing with JavaScript
Take a step back.
React Reflect
$(window).load(function () {
$('a.external-link').on('click', function clickHandler (e) {
e.preventDefault();
if (confirm(...
This is not separation of concerns.
<a class="hide-me">Click and I'll disappear</a>
<script type="application/javascript">...
Result driven
approach.
Just enough code to make it work.
Looks good
at the front.
Not so pretty
at the back.
Not good enough.
Doesn't supply what I
need.
We need:
1. Generated Elements; Templates?
2. XHR requests; Obviously, it's the future.
3. Data Handling; Models? Collecti...
Our saviours:
Backbone.js, Ember.js,
Angular.js
Backbone.JS: You figure it out.
var DocumentRow = Backbone.View.extend({
tagName: "li",
className: "document-row",
events:...
Angular.JS: ng-whatever.
<html ng-app="phonecatApp">
<head>
<script src="bower_components/angular/angular.js"></script>
<s...
Ember.JS: Handlebars / Mustache.
23 page doc needed to
explain views.
You don't like JS and
HTML; here's
something different.
It just doesn't work.
I'm OUT!
Back to HTML.
Back-end flow:
Receive HTTP Request.
Process & Collect Data.
Send Data => Template Engine.
Send HTTP Response.
Current Application
State in HTML
Declarative
<h1 class="hello">Hello World!</h1>
 
Composable
<div class="hello">
<h1 class="hello__message">Hello World!</...
State & Behaviour
<input type="checkbox" checked/>
Why can't it just be like that?
Just the UI
Just like HTML
React (JS)
Define
var HelloWorld = React.createClass({
render: function () {
return <h1>Hello, World!</h1>;
}
});
 
Use
React.render(...
HTML in my JS?!
What The Fudge!
#ProTip: Get over it.
JSX is just a DSL for
HTML in JavaScript
Sugar
var HelloWorld = React.createClass({
render: function () {
return <h1>Hello, World!<h1>;
}
});
Desugared
var HelloWorld = React.createClass({
render: function () {
return React.createElement(
'h1',
{className: 'hello_...
Just like HTML:
It's declarative
<ModalWindow/>
Just like HTML:
You can pass
properties
<ModalWindow opened={true}/>
Just like HTML:
It's composable.
<ModalWindow>
<ModalHeader title="Hello World"/>
<ModalBody>
...
</ModalBody>
</ModalWind...
It shows intent.
<ProfileEditor>
<Username />
<ProfilePicture />
<Biography />
</ProfileEditor>
But where do I put my data?
React is all about the bass UI.
What is data in the UI?
Properties & State
Properties
=
External Input
var Badge = React.createClass({
render: function () {
return <div className="badge">
<h1>{this.props.name}</h1>
<div>;
}
}...
var Badge = React.createClass({
render: function () {
var description = this.props.is_awesome
? 'is awesome!'
: 'is not aw...
var BadgeList = React.createClass({
render: function () {
var badges = this.props.people.map(function (person) {
return <B...
State
=
Internal
var Toggle = React.createClass({
getInitialState: function () {
return { completed: false };
},
render: function () {
var ...
var Toggle = React.createClass({
getInitialState: function () {
return { completed: false };
},
onClick: function () {
thi...
Nice but what about
MY data?
Back-end data flow:
1. Receive an HTTP request.
2. Process + Get relevant data.
3. Respond with a rendered view.
Back-end data flow:
1. Action (intention)
2. Domain (business stuff)
3. Response (json/html/ ... xml?)
How does this map to
JavaScript / React?
Front-end data flow:
1. Action (intention)
2. Domain (?)
3. Response (React)
Front-end data flow:
1. Action (intention)
2. Store / Services (data layer)
3. Response (React)
Stores hold the
application state.
Services interact
with APIs.
 
Flux
Flux is only a pattern
There are many implementations already.
Alt.js
Actions & Stores
/actions/
/stores/
/components/
/alt.js
/actions/TodoActions.js
/stores/TodoStore.js
/components/TodoApplication.js
/components/TodoList.js
import Alt from 'alt';
let alt = new Alt();
export default alt;
// actions/TodoActions.js
import alt from '../alt';
class TodoActions {
createTodo (task) {
this.dispatch({ task });
}
}
e...
// stores/TodoStore.js
import alt from '../alt';
import TodoActions from '../actions/TodoActions';
class TodoStore {
const...
import React from 'react';
var TodoApplication = React.createClass({
render() {
var todoList = this.state.todos.map(functi...
import TodoStore from '../stores/TodoStore';
var TodoApplication = React.createClass({
componentWillMount () {
TodoStore.l...
var TodoApplication = React.createClass({
render() {
var todoList = this.state.todos.map(function (todo, index) {
return <...
var TodoList = React.createClass({
render() {
var todoList = this.props.todos.map(function (todo, index) {
return <li key=...
import TodoList from './TodoList';
var TodoApplication = React.createClass({
render() {
return <div className="todos">
<To...
import TodoList from './TodoList';
import TodoActions from '../actions/TodoActions';
var TodoApplication = React.createCla...
So, what about my
Laravel App?
// routes.php
$app->post('/todos', function (Request $request) {
$todo = $request->json()->all();
// Store the TODO
return...
import alt from '../alt';
import TodoActions from '../actions/TodoActions';
class TodoStore {
handleCreatedTodo (todo) {
f...
What do we know so
far?
Writing front-end code, like back-end code.
It's all about data-flow.
Intent is everything.
Complexity should be facilitated.
Choose a tool that
supports it.
React can run
on the server.
Declarative UI
across the board.
Thank you for
your time!
Frontin like-a-backer
Frontin like-a-backer
Frontin like-a-backer
Frontin like-a-backer
Frontin like-a-backer
Frontin like-a-backer
Frontin like-a-backer
Frontin like-a-backer
Upcoming SlideShare
Loading in …5
×

Frontin like-a-backer

10,184 views

Published on

Apple back-end workflows in front-end code with React and Flux.

Published in: Software, Technology
  • Nice !! Download 100 % Free Ebooks, PPts, Study Notes, Novels, etc @ https://www.ThesisScientist.com
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Frontin like-a-backer

  1. 1. Frontin' Like A Back-er by @frankdejonge
  2. 2. The PHP League Flysystem
  3. 3. 2 million downloads, thank you!
  4. 4. There's no other option than using JavaScript. - most of my friends
  5. 5. JavaScript is a means to an end. - almost all of my friends
  6. 6. If JavaScript is required, I'll hire somebody. - my friends who have companies
  7. 7. If we hate something, why do we do it?
  8. 8. We all like the result: Snappy UI / UX
  9. 9. I made a server browser do this!
  10. 10. Loving JavaScript Hating JavaScript Dealing with JavaScript
  11. 11. Take a step back. React Reflect
  12. 12. $(window).load(function () { $('a.external-link').on('click', function clickHandler (e) { e.preventDefault(); if (confirm('Really?')) { $(this).off('click', clickHandler).click(); } }); });
  13. 13. This is not separation of concerns. <a class="hide-me">Click and I'll disappear</a> <script type="application/javascript"> $('a.hide_me').on('click', function (e) { e.preventDefault(); $(this).hide(); }); </script> It's error-prone.
  14. 14. Result driven approach. Just enough code to make it work.
  15. 15. Looks good at the front.
  16. 16. Not so pretty at the back.
  17. 17. Not good enough. Doesn't supply what I need.
  18. 18. We need: 1. Generated Elements; Templates? 2. XHR requests; Obviously, it's the future. 3. Data Handling; Models? Collections?
  19. 19. Our saviours: Backbone.js, Ember.js, Angular.js
  20. 20. Backbone.JS: You figure it out. var DocumentRow = Backbone.View.extend({ tagName: "li", className: "document-row", events: { "click .icon": "open", }, initialize: function() { this.listenTo(this.model, "change", this.render); }, render: function() { var idea = 'I have none'; } });
  21. 21. Angular.JS: ng-whatever. <html ng-app="phonecatApp"> <head> <script src="bower_components/angular/angular.js"></script> <script src="js/controllers.js"></script> </head> <body ng-controller="PhoneListCtrl"> <ul> <li ng-repeat="phone in phones"> <span>{{phone.name}}</span> <p>{{phone.snippet}}</p> </li> </ul> </body> </html>
  22. 22. Ember.JS: Handlebars / Mustache. 23 page doc needed to explain views.
  23. 23. You don't like JS and HTML; here's something different.
  24. 24. It just doesn't work.
  25. 25. I'm OUT! Back to HTML.
  26. 26. Back-end flow: Receive HTTP Request. Process & Collect Data. Send Data => Template Engine. Send HTTP Response.
  27. 27. Current Application State in HTML
  28. 28. Declarative <h1 class="hello">Hello World!</h1>   Composable <div class="hello"> <h1 class="hello__message">Hello World!</h1> </div>
  29. 29. State & Behaviour <input type="checkbox" checked/>
  30. 30. Why can't it just be like that? Just the UI Just like HTML
  31. 31. React (JS)
  32. 32. Define var HelloWorld = React.createClass({ render: function () { return <h1>Hello, World!</h1>; } });   Use React.render( <HelloWorld/>, document.getElementById('root') );
  33. 33. HTML in my JS?! What The Fudge!
  34. 34. #ProTip: Get over it.
  35. 35. JSX is just a DSL for HTML in JavaScript
  36. 36. Sugar var HelloWorld = React.createClass({ render: function () { return <h1>Hello, World!<h1>; } });
  37. 37. Desugared var HelloWorld = React.createClass({ render: function () { return React.createElement( 'h1', {className: 'hello_world'}, 'Hello, World!' ); } });
  38. 38. Just like HTML: It's declarative <ModalWindow/>
  39. 39. Just like HTML: You can pass properties <ModalWindow opened={true}/>
  40. 40. Just like HTML: It's composable. <ModalWindow> <ModalHeader title="Hello World"/> <ModalBody> ... </ModalBody> </ModalWindow>
  41. 41. It shows intent. <ProfileEditor> <Username /> <ProfilePicture /> <Biography /> </ProfileEditor>
  42. 42. But where do I put my data? React is all about the bass UI.
  43. 43. What is data in the UI? Properties & State
  44. 44. Properties = External Input
  45. 45. var Badge = React.createClass({ render: function () { return <div className="badge"> <h1>{this.props.name}</h1> <div>; } }); React.render( <Badge name="Kayla" />, document.getElementById('root') );
  46. 46. var Badge = React.createClass({ render: function () { var description = this.props.is_awesome ? 'is awesome!' : 'is not awesome'; return <div className="badge"> <h1>{this.props.text}</h1> <p> {description} </p> <div>; } }); React.render(<Badge name="Kayla" is_awesome={true} />, rootNode);
  47. 47. var BadgeList = React.createClass({ render: function () { var badges = this.props.people.map(function (person) { return <Badge key={person.id} {...person} />; }); return <div className="badge_list">{badges}<div>; } }); React.render(<BadgeList people={peopleCollection} />, rootNode);
  48. 48. State = Internal
  49. 49. var Toggle = React.createClass({ getInitialState: function () { return { completed: false }; }, render: function () { var className = this.state.completed ? 'toggle--completed' : 'toggle'; return <div className={className} />; } });
  50. 50. var Toggle = React.createClass({ getInitialState: function () { return { completed: false }; }, onClick: function () { this.setState({completed: ! this.state.completed}); }, render: function () { var className = this.state.completed ? 'toggle--completed' : 'toggle'; return <div onClick={this.onClick} className={className} />; } });
  51. 51. Nice but what about MY data?
  52. 52. Back-end data flow: 1. Receive an HTTP request. 2. Process + Get relevant data. 3. Respond with a rendered view.
  53. 53. Back-end data flow: 1. Action (intention) 2. Domain (business stuff) 3. Response (json/html/ ... xml?)
  54. 54. How does this map to JavaScript / React?
  55. 55. Front-end data flow: 1. Action (intention) 2. Domain (?) 3. Response (React)
  56. 56. Front-end data flow: 1. Action (intention) 2. Store / Services (data layer) 3. Response (React)
  57. 57. Stores hold the application state.
  58. 58. Services interact with APIs.
  59. 59.  
  60. 60. Flux
  61. 61. Flux is only a pattern There are many implementations already.
  62. 62. Alt.js Actions & Stores
  63. 63. /actions/ /stores/ /components/
  64. 64. /alt.js /actions/TodoActions.js /stores/TodoStore.js /components/TodoApplication.js /components/TodoList.js
  65. 65. import Alt from 'alt'; let alt = new Alt(); export default alt;
  66. 66. // actions/TodoActions.js import alt from '../alt'; class TodoActions { createTodo (task) { this.dispatch({ task }); } } export default alt.createActions(TodoActions);
  67. 67. // stores/TodoStore.js import alt from '../alt'; import TodoActions from '../actions/TodoActions'; class TodoStore { constructor() { this.todos = []; this.bindListeners({ handleCreatedTodo: TodoActions.CREATE_TODO }); } handleCreatedTodo (todo) { this.todos.push(todo); } } export default alt.createStore(TodoStore, 'TodoStore');
  68. 68. import React from 'react'; var TodoApplication = React.createClass({ render() { var todoList = this.state.todos.map(function (todo, index) { return <li key={index}>{todo.task}</li>; }); return <div className="todos"> <ul className="todo__list"> {todoList} </ul> <input type="text"/> </div>; } });
  69. 69. import TodoStore from '../stores/TodoStore'; var TodoApplication = React.createClass({ componentWillMount () { TodoStore.listen(this.handleChange); } componentWillUnmount () { TodoStore.unlisten(this.handleChange); } handleChange (state) { this.setState(state); } getInitialState() { return TodoStore.getState(); } });
  70. 70. var TodoApplication = React.createClass({ render() { var todoList = this.state.todos.map(function (todo, index) { return <li key={index}>{todo.task}</li>; }); return <div className="todos"> <ul className="todo__list"> {todoList} </ul> <input type="text"/> </div>; } });
  71. 71. var TodoList = React.createClass({ render() { var todoList = this.props.todos.map(function (todo, index) { return <li key={index}>{todo.task}</li>; }); return <ul className="todo__list"> {todoList} </ul>; } });
  72. 72. import TodoList from './TodoList'; var TodoApplication = React.createClass({ render() { return <div className="todos"> <TodoList todos={this.state.todos} /> <input type="text"/> </div>; } });
  73. 73. import TodoList from './TodoList'; import TodoActions from '../actions/TodoActions'; var TodoApplication = React.createClass({ handleCreateTodo (event) { if (event.keyCode !== 13) return; var task = event.target.value; TodoAction.createTodo(task); } render() { return <div className="todos"> <TodoList todos={this.state.todos} /> <input type="text" onKeyDown={this.handleCreateTodo}/> </div>; } });
  74. 74. So, what about my Laravel App?
  75. 75. // routes.php $app->post('/todos', function (Request $request) { $todo = $request->json()->all(); // Store the TODO return new JsonResponse($todo->all()); });
  76. 76. import alt from '../alt'; import TodoActions from '../actions/TodoActions'; class TodoStore { handleCreatedTodo (todo) { fetch('/todos', { method: 'post', body: JSON.stringify(todo) }).then((response) => { this.todos.push(response.json()); this.emitChange(); }); } } export default alt.createStore(TodoStore, 'TodoStore');
  77. 77. What do we know so far?
  78. 78. Writing front-end code, like back-end code. It's all about data-flow.
  79. 79. Intent is everything.
  80. 80. Complexity should be facilitated. Choose a tool that supports it.
  81. 81. React can run on the server.
  82. 82. Declarative UI across the board.
  83. 83. Thank you for your time!

×