React Binding Patterns: 5 Approaches for Handling this

1-YJI4x0i0lJA110oRvjwNBw

Cory House:

There are at least five ways to handle the this context in React. Let’s consider the merits of each approach.

  1. Use React.createClass
  2. Bind in Render
  3. Use Arrow Function in Render
  4. Bind in Constructor
  5. Use Arrow Function in Class Property

Currently I’m mostly using Approach 4 (“Bind in Constructor”), but Approach 5 (“Arrow Function in Class Property”) looks like something to switch to after having read the post.

React Binding Patterns: 5 Approaches for Handling this

On a sidenote, ES2017+ will sport the Function Bind Operator (::) which acts a a shorthand for .bind(context).

// ES2015
this.logMessage = this.logMessage.bind(this);

// ES2017
this.logMessage = ::this.logMessage;

JavaScript ES7 Function Bind Syntax →

React Storybook – Isolate your React UI Component development from the main app

react_storybook_screenshot

With React Storybook, you can develop and design UI components outside your app in an isolated environment. It will change how you develop UI components.

Oh, it also plays nice with create-react-app.

React Storybook →
Introducing React Storybook →
React Storybooks meets Create React App →

Creating a React app with create-react-app

react-opti

Tyler McGinnis, after having been involved in quite a lot of tutorials/courses/workshops teaching on how to build a React app:

Throughout all of these workshops, one thing was consistent: getting started with a React application was pretty overwhelming, for both beginners and senior developers alike.

I can confirm this I must say. The tutorials and documentation of React are fine (if not excellent), yet it took me quite some time to actually get started. Problems arose everywhere and in the beginning I wasn’t all too sure if it was either Webpack, or Babel, or my ES6 skills, or something else that was failing.

With the recent publication of create-react-app things are now about to change though:

“create-react-app” is an official command line interface (CLI) for building React applications with no build configuration.

Usage is simple:

npm install -g create-react-app
create-react-app Awesome

Et voila, you’re ready to start building your React app. No need to worry about setting up Webpack/Babbel/etc … it’s all there.

create-react-app and the future of creating React applications →
create-react-app — Create React apps with no build configuration. →

Distributing your React Component as a Standalone Version

react-opti

At work we’ve been building quite some stuff on top of React the past few months. We use Grunt (and more recently Webpack) to run browserify with the babelify transform to transpile our ES6 code into ES5.

Earlier this week I came to the point where I wanted to distribute a built component as a standalone .js file, for inclusion in the browser by 3rd party developers (in case they don’t know React themselves, or use ES5, or just don’t want to include the component’s source).

Building that standalone version comes with a few prerequisites:

  1. No copy of react nor react-dom should be included in the component itself – just like a jQuery plugin does not include jQuery itself but relies on it being available instead.
  2. The contained classes should be accessible on a single namespace to the 3rd party developer.

That way an implementer could include the component as follows:

<-- Include react and react-dom -->
<script type="text/javascript" src="/libs/react/15.2.1/react.js"></script>
<script type="text/javascript" src="/libs/react/15.2.1/react-dom.js"></script>

<-- Include the Component -->
<script type="text/javascript" src="/script/my-react-component.js"></script>

<-- Use the Component -->
<script type="text/javascript">
  var c = new MyComponent.Player();
</script>

To get this working, I had to make a few adjustments into the build script:

  1. Prevent both the react and react-dom packages from being included into my distributable file, using browserify’s external option. This option will tell browserify to not try and include react/react-dom whenever it encounters an import/require() for one of those packages, but to trust us to them being available.
  2. Transform all import/require() calls for react/react-dom to use the external (global) copies of React, using the browserify-global-shim transform for Browserify.
  3. Define a (global) namespace into which all of my classes will become available, using browserify’s standalone option.

Puzzling all pieces together, our browserify Grunt task to build the standalone/distrubutable version looks like this:

{
	dist: {
		src: ['src/index.js'],
		dest: 'dist/my-react-component.js',
		options: {
			watch: false,
			external: [
				'react',
				'react-dom',
			],
			transform: [['babelify', {
				presets: ['react', 'es2015'],
				compact: false,
				plugins: ['transform-class-properties', 'transform-object-rest-spread', 'add-module-exports']
			}], ['browserify-global-shim', {
				"react": "React",
				"react-dom": "ReactDOM"
			}]],
			browserifyOptions: {
				extensions: ['.js'],
				debug: false,
				standalone: 'MyComponent'
			}
		}
	}
}

In summary:

  1. options.external prevents react/react-dom from being included locally into the dist file itself,
  2. The entry browserify-global-shim (along with its own options) in options.transform wires the import/require() calls for react/react-dom to the global versions as the local versions don’t exist,
  3. options.browserifyOptions.standalone defines the namespace which gets exported globally.
Did this help you out? Like what you see?
Consider donating.

I don’t run ads on my blog nor do I do this for profit. A donation however would always put a smile on my face though. Thanks!

☕️ Buy me a Coffee ($3)

Getting Started with Redux

EGH_Redux-New-cover

Managing state in an application is critical, and is often done haphazardly. Redux provides a state container for JavaScript applications that will help your applications behave consistently.

Redux is an evolution of the ideas presented by Facebook’s Flux, avoiding the complexity found in Flux by looking to how applications are built with the Elm language.

“Getting Started with Redux” is a free set of video tutorials by the Redux author, Dan Abramov, himself on working with Redux. I found these very easy to follow and understand.

There’s also a follow-up set entitled “Building React Applications with Idiomatic Redux”

Egghead.io: Getting Started with Redux →
Egghead.io: Building React Applications with Idiomatic Redux →

Pepperoni – A delicious blueprint for mobile development

pepperoni

Pepperoni is a blueprint for building cross-platform mobile experiences rapidly with ready-to-use integrated building blocks for common mobile app features, powered by React Native.

The Pepperoni blueprint is crafted on a solid foundation using modern architecture and industry best practices.

Pepperoni →

Draft.js – Rich Text Editor Framework for React

Draft.js is a framework for building rich text editors in React, powered by an immutable model and abstracting over cross-browser differences.

Draft.js makes it easy to build any type of rich text input, whether you’re just looking to support a few inline text styles or building a complex text editor for composing long-form articles.

The framework is used by Facebook itself, and is perfectly explained in this video from React.JS Conf 2016:

Some neat experiments, such as Draft-WYSIWYG, have already been built upon Draft.js.

Draft.js →
Draft-WYSIWYG Source (GitHub) →
Draft-WYSIWYG Demo →

Redux DevTools Chrome Extension

A Chrome DevTools Extension, wrapping around Redux DevTools:

redux-devtools-extension

The Redux DevTools themselves are a live-editing time travel environment for Redux:

Redux DevTools

  • Lets you inspect every state and action payload
  • Lets you go back in time by “cancelling” actions
  • If you change the reducer code, each “staged” action will be re-evaluated
  • If the reducers throw, you will see during which action this happened, and what the error was
  • With persistState() store enhancer, you can persist debug sessions across page reloads

Redux DevTools →
Redux DevTools Chrome Extension (Source) →
Redux DevTools Chrome Extension (Chrome Web Store) →

Motion Design in React.js with “React Motion”

import {Motion, spring} from 'react-motion';

// In your render:
<Motion defaultStyle={{x: 0}} style={{x: spring(10)}}>
  {value => <div>{value.x}</div>}
</Motion>

This library provides an alternative, more powerful API for React’s TransitionGroup. For 95% of use-cases of animating components, we don’t have to resort to using hard-coded easing curves and duration. Set up a stiffness and damping for your UI element, and let the magic of physics take care of the rest. This way, you don’t have to worry about petty situations such as interrupted animation behavior. It also greatly simplifies the API.

Here’s a talk by the author on React Motion:

React Motion →

Motion Design in React.js: UI Animations with CSSTransitionGroup and TransitionGroup

react-animations-disabled react-animations-enabled
React Interface without (left) and with (right) animations

In this article, I am going to use the official components from React.js addons. There are other components/libraries that are better for the job but at the end of the article you will get a good amount of React.js animation practice to better understand these other components.

First the CSSTransitionGroup is covered:

const List = ({items, onRemoveItem}) => {
  const listItems = items.map((item, idx) => {
    return <ListItem key={item} onClick={onRemoveItem.bind(this, idx)}/>
  })

  return (
    <div className="list">
      <CSSTransitionGroup transitionName="list__item-" transitionEnterTimeout={500} transitionLeaveTimeout={500}>
        {listItems}
      </CSSTransitionGroup>
    </div>
  )
}
@keyframes add-item {
  from { transform: scale(0, 0); }
  75% { transform: scale(1.1, 1.1); }
  to { transform: scale(1, 1); }
}
@keyframes remove-item {
  from { transform: scale(1, 1); }
  25% { transform: scale(1.1, 1.1); }
  to { transform: scale(0, 0); }
}

.list__item--enter {
  animation-name: add-item;
  animation-duration: 500ms;
}
.list__item--leave {
  background: #bf4a3c;
  animation-name: remove-item;
  animation-duration: 520ms;
}

Once you get the gist of CSSTransitionGroup, the move to the underlying TransitionGroup (which gives you more control, yet is more “raw” in use) is easy

Improve React.js apps with Motion Design →
Improve React.js apps with Motion Design Source (GitHub) →