React: The Good, the Bad, & the Ugly

What is React?

React is a library, not a framework

  • Data -> View
  • Uses a 'Shadow DOM'
  • Reconciliation

import React, { Component } from 'react';
import { render } from 'react-dom';

class App extends Component {
  constructor() {
    super(...arguments);
    this.state = {
      thisCan: 'be whatever you want'
    };

    this.setState({
      and: 'can be managed and abstracted',
      however: 'you wish'
    });
  }

  render() {
    return (
      <div>
        Hello World
        {this.state.thisCan}
      </div>
    );
  }
}

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

The Good

React doesn't care

  • Give it a base state
  • Mutate VIA provided tools
  • Data can be from anywhere

import React, { Component } from 'react';
import { render } from 'react-dom';


class App extends Component {
  constructor(...args) {
    super(...args);
    this.state = {
      currentCount: 0
    };
    setInterval(() => {
      this.setState({
        currentCount: this.state.currentCount + 1
      });
      //Every time setState is called,
      //React diff's the changed state and fires off a DOM update!
    }, 100);
  }

  render() {
    const { currentCount } = this.state;
    return (
      <div>Count: {currentCount}</div>
    );
  }
}

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

JSX

  • Logic in the view
  • render() can handle JSX, HTML, or Javascript
  • Can be abstracted

import React, { Component } from 'react';
import { render } from 'react-dom';

class App extends Component {
  render() {
    return (
      <div>
        Hello World
        <span className='container'>
          Goodbye World
        </span>
      </div>
    );
  }
}

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

Component Emphasis

  • Compartmentalize Everything
  • Easy abstraction to keep things organized
  • Complexity is up to you
import React, { Component } from 'react';
import { render } from 'react-dom';

class SubComponent extends Component {
  render() {
    return (
      <div>
        I am a sub component!
      </div>
    );
  }
}
const subComponent = <SubComponent />;

class App extends Component {
  render() {
    return (
      <div>
        You always need a wrapper element!
        <SubComponent /> { /* Comments in JSX need to be within braces */ }
        { /* Components need to have the first letter capitalized! */ }
        { /* <subComponent /> will not work! */ }
        {subComponent /* This works because we're rendering a variable */}
      </div>
    );
  }
}

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

Speed

  • React renders things quickly
  • Set the standard for the industry

Active Community

  • 957 Contributors
  • 26208 packages found for "react" on npm

  • Backed by numerous large companies, notably Facebook

Powerful and Numerous Community-Supported Modules

  • React is lightweight, lots to extend on
  • Redux, MobX, Cerebral
  • React-router

Multi-Platform

  • Reconciliation...
  • React-DOM
  • React-Native
  • React-VR

React-Fiber

  • Rewrite of the Reconciliation Engine
  • 92.2% complete as of now

The Bad

Facebook

  • Who really needs privacy?
  • Sketchy License
  • Lawyers have disallowed use of React in certain scenarios

Webpack & Getting Started Overhead

Just install...

  • Webpack
  • Babel
  • All necessary presets
  • Transformers
  • Plugins

const path = require('path');

const BUILD_DIR = path.resolve(__dirname, '../server/static/');
const APP_DIR = path.resolve(__dirname, './app');

const TARGET = process.env.npm_lifecycle_event;
process.env.BABEL_ENV = TARGET;

const config = {
  entry: [
    APP_DIR + '/index.jsx'
  ],
  output: {
    path: BUILD_DIR,
    filename: 'bundle.js'
  },
  module : {
    loaders : [
      {
        test : /\.jsx?/,
        include : APP_DIR,
        loader : 'babel'
      },
      {
        test: /\.(png|jpg)$/,
        include : APP_DIR,
        loader: 'url-loader?limit=8192'
      },
      {
        test: /\.js$/,
        include: APP_DIR,
        loader: 'babel'
      },
      {
        test: /\.json$/,
        include: APP_DIR,
        loader: 'babel'
      }
    ],
  },
  resolve: {
    extensions: [
      '',
      '.js',
      '.jsx',
      '.css',
      '.scss'
    ]
  }
};

module.exports = config;

webpack.config.js

State Management

class A extends Component {
  constructor(...args) {
    super(...args);
    this.state = {
      a: 'b'
    }
  }
}

class B extends Component {
  constructor(...args) {
    super(...args);
    this.state = {
      b: 'a'
    }
  }
}

State managed per-component

Requires external libraries to sync across components

class A extends Component {
  constructor(...args) {
    super(...args);
    this.state = {
      a: 'b'
    }
  }

  render() {
    return <B a={this.state.a} />
  }
}

class B extends Component {
  constructor(...args) {
    super(...args);
    this.state = {
      b: this.props.a || 'a'
    }
  }
}

Functional Components

class A extends Component {
  constructor(...args) {
    super(...args);
    this.state = {
      a: 'b'
    }
  }

  render() {
    return <B a={this.state.a} />
  }
}

const B = function(props) {
  return (
    <div>{props.a || 'a'}</div>
  );
}

Modeling Complex Objects

  • Heavy emphasis on breaking things down means when you can't, you have trouble
  • Rendering recursively ends up okay, but editing gets messy
  • No 2-way binding prevents an easy solution

The Ugly

JSX, again

  • Tightly couples view with logic
  • Discourages more elegant abstractions
  • Literally just syntactic sugar
class Hello extends React.Component {
  render() {
    return (
      <div>
        Hello {this.props.toWhat}
      </div>
    );
  }
}

class Hello extends React.Component {
  render() {
    return React.createElement(
      'div',
      null,
      `Hello ${this.props.toWhat}`
    );
  }
}

Clunky Addons

  • Limited base app leads to lots of modules
  • Hugely varied codebases mean not all modules will play nice
  • Isomorphism, Hot-Loader

Javascript

You're writing Javascript.

Your team is writing Javascript.

React isn't picky about what you do, and....

Most people suck at writing Javascript.

State Management

  • Redux?
  • MobX? Cerebral?
  • DIY?

Shameless Plug, Redux Black Magic:

https://github.com/krishnaglick/redux-black-magic

Overall?

  • Powerful
  • Reliable
  • Worth the trouble

Contact

/krishnaglick on Github

@krishnaglick on Twitter

@prometheus on ODevs Slack

Made with Slides.com