Why React is a game changer

in frontend development

Time To React

Internet nowadays

Holy shit, another Javascript library.

Everything is fine. Old ways are working fine.

React fundamentally changes an equation we've all been working with for years, and an idea can be much more powerful than the technology implementing it.

 

Nicholas C. Zakas

Yeah yeah, Mr. Fancy Quotes. Get to the point.

Problems

  • Performance - making changes to the DOM is slow due to repaint and reflow
  • Efficiency - you can end up creating memory leaks by losing track of node references or by forgetting to detach event handlers

  • Complexity - hard to maintain, hard to understand

  • Scalability - hard to add new features and change design
  • Reusability - hard to reuse UI code across different websites and applications

Solutions

  • make only small DOM changes
  • work in detached DOM and then reattach it
  • manually destruct DOM references and UI entities
  • manually keep track on all event handlers
  • work out some kind of a code convention
  • try to use some huge framework doing too much 
  • attempts to modularise UI pieces by using string-based template engines

React to the rescue: TLDR;

  • less DOM manipulations -> better UI performance
  • event handlers attach/detach automatically -> no more memory leaks

  • we do much less manually -> apps are simpler and more scalable

  • declarative code -> easy to reason about

  • components -> reusability, encapsulation, testability

  • UI development is standardised

Let's start with...

jQuery

<span id="colored-counter">0</span>
<input id="color" placeholder="color">
<button id="inc">increase</button>

<script>
$('#color').on('keyup', function () {
    $('#colored-counter').css('color', this.value);
})

$('#inc').on('click', function () {
    var oldValue = $('#colored-counter').html();
    var newValue = 1 + Number(oldValue);
    $('#colored-counter').html(newValue);
})
</script>

Let's start with... jQuery

<span id="colored-counter">0</span>
<input id="color" placeholder="color">
<button id="inc">increase</button>

<script>
var state = {color: '', value: 0};

function updateUI() {
    $('#colored-counter').css('color', state.color);
    $('#colored-counter').html(state.value);
}

$('#color').on('keyup', function () {
    state.color = this.value;
    updateUI();
})

$('#inc').on('click', function () {
    state.value++;
    updateUI();
})
</script>

React idea at its simplest

Data flow comparison

Simple way: is really simple

“React” way: looks over-engineered

Raising complexity

Simple way: is not that simple anymore

Raising complexity

“React” way: suddenly it's simple now!

Interesting...

React key concepts: Render.

Reactive Render.

Render: rough picture

<span id="colored-counter">0</span>
<input id="color" placeholder="color">
<button id="inc">increase</button>

<script>
var state = {color: '', value: 0};

function updateUI() {
    $('#colored-counter').css('color', state.color);
    $('#colored-counter').html(state.value);
    window.requestAnimationFrame(updateUI);
}

$('#color').on('keyup', function () {
    state.color = this.value;
});

$('#inc').on('click', function () {
    state.value++;
});

updateUI();
</script>

Render in React: the surface

var ColoredCounter = React.createClass({
  getInitialState: function() {
    return { color: '', value: 0 };
  },

  onColorChange: function(e) {
    this.setState({ color: e.target.value });
  },

  onValueChange: function() {
    this.setState({ value: this.state.value + 1 });
  },

  render: function() {
    return (
      <div>
        <span style={{ color: this.state.color }}>{ this.state.value }</span>
        <input placeholder="color" onKeyUp={ this.onColorChange } />
        <button onClick={ this.onValueChange }>increase</button>
      </div>
    );
  }
});

ReactDOM.render(<ColoredCounter />, document.getElementById('app'));

Render in React: under the hood

var ColoredCounter = React.createClass({
  getInitialState: function() {
    return { color: '', value: 0 };
  },

  onColorChange: function(e) {
    this.setState({ color: e.target.value });
  },

  onValueChange: function() {
    this.setState({ value: this.state.value + 1 });
  },

  render: function() {
    return (
      <div>
        <span style={{ color: this.state.color }}>{ this.state.value }</span>
        <input placeholder="color" onKeyUp={ this.onColorChange } />
        <button onClick={ this.onValueChange }>increase</button>
      </div>
    );
  }
});

ReactDOM.render(<ColoredCounter />, document.getElementById('app'));

Reactivity, bitch!

Good old excel

JSX

  //...
  render: function() {
    return (
      <div>
        <span style={{ color: this.state.color }}>{ this.state.value }</span>
        <input placeholder="color" onKeyUp={ this.onColorChange } />
        <button onClick={ this.onValueChange }>increase</button>
      </div>
    );
  }
  //...
const $ = React.createElement;

  //...
  render: function() {
    return (
      $('div', null,
        $('span', { style: { color: this.state.color } }, this.state.value),
        $('input', { placeholder: 'color', onKeyUp: this.onColorChange }),
        $('button', { onClick: this.onValueChange }, 'increase')
      )
    );
  }
  //...

React key concepts: Components

Components

  • the most fundamental part of React
  • building blocks of UI
  • encapsulated DOM structure

  • encapsulated DOM logic

  • automated DOM interactions

  • highly reusable

Components: ES5-example

var ColoredCounter = React.createClass({
  getInitialState: function() {
    return { color: '', value: 0 };
  },

  onColorChange: function(e) {
    this.setState({ color: e.target.value });
  },

  onValueChange: function() {
    this.setState({ value: this.state.value + 1 });
  },

  render: function() {
    return (
      <div>
        <span style={{ color: this.state.color }}>{ this.state.value }</span>
        <input placeholder="color" onKeyUp={ this.onColorChange } />
        <button id="inc" onClick={ this.onValueChange }>increase</button>
      </div>
    );
  }
});

ReactDOM.render(<ColoredCounter />, document.getElementById('app'));

Components: ES2015-example

class ColoredCounter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { color: '', value: 0 };
  }

  onColorChange = e => {
    this.setState({ color: e.target.value });
  };

  onValueChange = () => {
    this.setState({ value: this.state.value + 1 });
  };

  render() {
    return (
      <div>
        <span style={{ color: this.state.color }}>{ this.state.value }</span>
        <input placeholder="color" onKeyUp={ this.onColorChange } />
        <button id="inc" onClick={ this.onValueChange }>increase</button>
      </div>
    );
  }
}
ReactDOM.render(<ColoredCounter />, document.getElementById('app'));

Mixing templates and logic?

Templates can be simple...

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>

  {{#each comments}}
    <h2>By {{fullName author}}</h2>
    <div class="comment">{{text}}</div>
  {{/each}}
</div>

...until they're not

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>

  {{#each comments}}
    <h2>By {{fullName author}}</h2>
    <div class="comment">{{text}}</div>
  {{/each}}

  <form>
    <textarea></textarea>
    <button>Add new comment</button>
  </form>
</div>

hardcoded IDs?

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>

  {{#each comments}}
    <h2>By {{fullName author}}</h2>
    <div class="comment">{{text}}</div>
  {{/each}}

  <form id="newComment">
    <textarea id="commentText"></textarea>
    <button>Add new comment</button>
  </form>
</div>

dynamic IDs?

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>

  {{#each comments}}
    <h2>By {{fullName author}}</h2>
    <div class="comment">{{text}}</div>
  {{/each}}

  <form id="{{commentFormID}}">
    <textarea id="{{commentFormTextID}}"></textarea>
    <button>Add new comment</button>
  </form>
</div>

Search by className/whatever attribute?

<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>

  {{#each comments}}
    <h2>By {{fullName author}}</h2>
    <div class="comment">{{text}}</div>
  {{/each}}

  <form class="comment-form">
    <textarea class="comment-text"></textarea>
    <button>Add new comment</button>
  </form>
</div>

More complex cases

Eventually, separation becomes artificial

No matter how you structure your project, there is no separation anymore

Nested components and props

class ColoredCounter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { color: '', value: 0 };
  }

  onColorChange = e => {
    this.setState({ color: e.target.value });
  };

  onValueChange = () => {
    this.setState({ value: this.state.value + 1 });
  };

  render() {
    return (
      <div>
        <span style={{ color: this.state.color }}>{ this.state.value }</span>
        <input placeholder="color" onKeyUp={ this.onColorChange } />
        <button id="inc" onClick={ this.onValueChange }>increase</button>
      </div>
    );
  }
}
class ColoredCounter extends React.Component {
  // constructor, event handlers, etc.

  render() {
    return (
      <div>
        <Counter color={this.state.color} value={this.state.value} />
        <input placeholder="color" onKeyUp={ this.onColorChange } />
        <button id="inc" onClick={ this.onValueChange }>increase</button>
      </div>
    );
  }
}
class Counter extends React.Component {
  render() {
      return (
        <span style={{ color: this.props.color }}>{ this.props.value }</span>
      );
  }
}

Nested components and props

class ColoredCounter extends React.Component {
  // constructor, event handlers, etc.

  render() {
    return (
      <div>
        <Counter color={this.state.color}>{this.state.value}</Counter>
        <input placeholder="color" onKeyUp={ this.onColorChange } />
        <button id="inc" onClick={ this.onValueChange }>increase</button>
      </div>
    );
  }
}
class Counter extends React.Component {
  render() {
      return (
        <span style={{ color: this.props.color }}>{ this.props.children }</span>
      );
  }
};

Children

class ColoredCounter extends React.Component {
  // constructor, event handlers, etc.

  render() {
    return (
      <div>
        <Counter color={this.state.color}>{this.state.value}</Counter>
        <input placeholder="color" onKeyUp={ this.onColorChange } />
        <button id="inc" onClick={ this.onValueChange }>increase</button>
      </div>
    );
  }
}
const Counter = function(props) {
  return <span style={{ color: props.color }}>{ props.value }</span>;
};

Stateless components

One-way data flow

props

props

props

props

props

state

state

props

props

props

onChange

You can use jQuery (but really shouldn't)

class DatePicker extends React.Component {
  componentDidMount() {
    $(this.refs.datepicker).datepicker();
  }
  
  render() {
    return (
      <p>
        <input placeholder="click me" type="text" ref="datepicker" />
      </p>
    );
  }
}

ReactDOM.render(<DatePicker />, document.getElementById('app'));

There is more...

  • lifecycle methods
  • controlled/uncontrolled components

  • propTypes

  • context

  • dynamic children

  • server-side rendering

  • React Native

  • testing

  • ...

Why not... Angular, Ember, etc.?

  • they are huge and monolithic frameworks, while React is just a view library
  • they are too opinionated
  • you still have to worry about DOM too much
  • bad performance
  • server rendering is impossible hard

Why not... web-components?

  • while solving encapsulation and componentisation they still make you do lot's of work with DOM manually
  • web-components are imperative while React is declarative
  • still raw and not finalized

Why not... React-like solutions?

  • Cycle
  • Elm
  • Deku
  • Riot
  • Vue.js
  • more...

They are great and you can use them, but...

community

Conclusion: why React?

  • automates manual work, less chances of mistakes

  • optimising DOM interactions -> great UI performance

  • simplifies data-flow and makes it predictable

  • works great for teams, enforcing to follow good patterns

  • declarative UI code is readable and maintainable

  • componentization is the future of web development

  • not opinionated about your app structure

  • huge community and ready-to-use components and modules

Is it ready for production?

YES

Desktop email-client: Nylas N1

Web browser: Vivaldi

Terminal renderer: react-blessed

React is the best thing since XMLHttpRequest

 

James K. Nelson

Links

Official links:
Documentation

Github

Thanks!

Made with Slides.com