Blog

Here we share our experiences, ideas, tips, and thoughts on React, Angular, Industry in general, and some other things.

Jafar Husain on async/await

Ilya Gelman

With latest browsers and NodeJS support, features like async/await are becoming the norm in modern web-development. For new developers, especially for those who’s JavaScript is their first language, it is very important to deeply understand how such features work to make the most out of them.

In his talk from JSConf US 2015, Jafar Husain explains async programming features in newest versions of JavaScript including promises, generators, and async functions.

On Thursdays we post videos that we believe are worth watching and that can make you a better front-end developer. Have such a video to share? Share with us

Dependency Injection in React With Provider Pattern

Adam Klein

The Provider pattern introduces a way to access some global object (service) in deeply nested components. If you’ve been using React for a while, you probably used it already. In fact, many popular libraries use this pattern: react-router, react-redux, mobx-react, react-intl, react-dnd, or styled-components.

A provider that wraps a component tree:

<Provider>
  <Component/>
</Provider>

An injector as higher-order function:

export default withProvider(Component);

You can also relate to this pattern as dependency injection as a mechanism of exposing a global dependency to nested components on demand, somewhat similar to Angular’s mechanism, but not as a general definition of dependency injection in software development.

Let’s say we want to create a customizable theme for our app and use it in any component we’d like:

const SendButton = () => (
  <button style={{ color: theme.primaryColor }}>Send</button>
);

Somehow we need the theme instance to be available in this component. Moreover, we want to make it reactive, meaning whenever we change the theme, we want the component to update.

Let’s start by creating a top-level component that will hold the theme, and pass it down using React context:

export class ThemeProvider extends React.Component {
  state = {
    primaryColor: '#448866'
  };

  static childContextTypes = {...};

  getChildContext() {
    return {
      getTheme: () => this.state
    };
  }

  render() {
    return <span>{ this.props.children }</span>;
  }  
};

Next, we’ll put the provider in the top-level of our app, to make the theme available everywhere:

const App = () => (
  <ThemeProvider>
    ...
  </ThemeProvider>
);

Now we need a way to access the theme from child components. We could do it directly from the context, but there are a few drawbacks to this:

  • Using context directly is not the best practice;
  • We are coupling our components to ThemeProvider;
  • We can’t use React’s lifecycle hooks to react to changes in theme.

So instead we use an injector:

function withTheme(WrappedComponent) {
  const Wrapper = (props, { getTheme }) => (
    <WrappedComponent
      getTheme={ getTheme }
      { ...props }
    />
  );

  Wrapper.contextTypes = {...};

  return Wrapper;
}

The injector is a higher-order component (HOC) that takes the theme from the context and passes it down as props. Now to use the theme inside a component, you wrap it with the withTheme HOC:

const Component = (props) => (
  <div style={{ color: props.getTheme().primaryColor }}>
    This is the primary color
  </div>
);

export default withTheme(Component);

Reusing a service

Let’s now say we want to have two different themes side by side on our page. Since we are using context, we just need to put two ThemeProvider’s and each one of them will supply a different theme instance for its component subtree:

<div>
  Theme 1:
  <ThemeProvider>
     ... // components using theme 1
  </ThemeProvider>

  Theme 2:
  <ThemeProvider>
    ... // components using theme 2
  </ThemeProvider>
</div>

See full source code and demo on StackBlitz

When to use the pattern

Usually you can use generic store mechanisms like React and MobX to access global resources, but in some cases Redux and MobX are not good enough:

  • You are creating a generic component that should serve any architecture (for example if you create styled-components and want to supply a theme);
  • You need the services to be reusable on the page, and be able to declare a service per component tree;
  • You need to save large amounts of data that you don’t want on the store.

Other (bad) approaches

You could pass the theme down the component tree as a prop. In this case all the component’s ancestors have to be aware of the theme and pass it down which creates coupling, and is not a very productive way of writing code.

You could also export a theme object and import it wherever you need. In this case it won’t be reactive out of the box, meaning if we change the theme it won’t be reflected in the components that use it. Also, if we want to support showing two themes on the same page we can’t do that with a global singleton.

Lara Hogan on Optimizing Images and Fonts

Ilya Gelman

Performance optimization is crucial in many websites especially when you think of mobile devices and people with slower internet connection.

In her talk from Velocity 2015 conference, Lara Hogan talks about optimizing images and fonts on the web.

On Thursdays we post videos that we believe are worth watching and that can make you a better front-end developer. Have such a video to share? Share with us

Useful Tool: Regex 101

Ilya Gelman

Sometimes we need to write or understand complex regular expressions. It might be hard to remember all the syntax tokens, especially if not dealing with RegExp on a daily basis.

There’s a great tool called Regex 101 that can ease the pain. It lets you write a regular expression and test it on example inputs, providing visual explanation of what the heck is going on. It also shows the match information for the expression so you can know what values to expect when testing a string in code.

There’s also a quick reference in case you need to refresh your memory. Just make sure you select the JavaScript “flavor” in the left sidebar.

Earlier Ctrl + ↓