ac

Workloads, acceleration, and making Postgres better

#353 — April 29, 2020

Read on the Web

Postgres Weekly

7 Things That Could Be Improved in Postgres — As 1990s dance pop group D:Ream sang in 1994, Things Can Only Get Better.. including Postgres ???? Luckily these are all ‘nice to have’s but I dare say we’ll see some of them (such as automatic tuning and auto-vacuuming improvements) appear over time.

Kaarel Moppel

How The Citus Distributed Query Executor Adapts to a Postgres Workload — Citus is the popular extension for horizontally scaling Postgres and its query executor has seen some huge updates lately.

Citus Data (Microsoft)

eBook: The Most Important Events to Monitor in Your Postgres Logs — In this pganalyze eBook, we are looking at the Top 6 Postgres log events for monitoring query performance and preventing downtime.

pganalyze sponsor

Swarm64 DA 4.0: A Database Acceleration Extension for Postgres — Swarm64 started life as a FPGA-driven way to accelerate Postgres performance, but can now work without FPGAs too. This is not a free product but if you want to give it a run, there’s a trial or it can be spun up from the AWS Marketplace.

Yana Krasteva

Postgres Performance Goalposts — An interesting heuristic from Bruce here on what to do if you expect your connections, queries, or write queries to be above/below certain levels.

Bruce Momjian

A Tale of Password Authentication Methods in Postgres“Let’s say you want to implement a password authentication method in a client/server protocol..” Here’s the story of how Postgres came up with its approaches.

Peter Eisentraut

How to Set application_name When Using psql — As Craig says: “Setting your application name in Postgres is SO USEFUL. It will help a lot for debugging when you’ve got multiple different apps/services connecting to the same database.”

Denish Patel

How to Upgrade Postgres from v11 to v12 on Ubuntu 20.04 — Now that Ubuntu 20.04 is out, this might be on your mind!

Paolo Melchiorre

Working with Amazon Aurora PostgreSQL: What Happened to the Stats? — Apparently there’s a bug with numerous versions of Aurora PostgreSQL that causes certain stats to be lost on restart.

Michael Vitale

Postgres Vision 2020 - Free Online Conference (June 23-24) — Learn how today’s IT leaders are using Postgres. Join from anywhere in the world and listen from 30+ Postgres experts.

EnterpriseDB sponsor

A Deep Dive into PostGIS Nearest Neighbor Search — Take a deep dive into the Postgres and PostGIS internals to find out how K-nearest neighbor accelerates local search.

Martin Davis

My Favorite Postgres Extensions: Part One — A basic high level look at pg_partman and postgres_fdw.

Nawaz Ahmed

Kanel: Generate TypeScript Types from Postgres

Kristian Dupont

Postgres.app: The Easiest Way to Get Started with Postgres on the Mac — I’ve used this for years, it’s super popular, but if there’s just a handful of developers out there who’d benefit from it and don’t know about it, this reminder will be worth it :-) It continues to get very frequent updates.

Jakob Egger, Chris Pastl, and Mattt Thompson

???? Upcoming Events

All in-person events we had listed are cancelled or postponed due to the COVID outbreak, so we're now linking to webinars, livestreams, and similar online events.

If you have any, just hit reply and if it's Postgres related (and either free or not too expensive) we'll include it in a future issue. Just one this week:

  • ???? Postgres Vision 2020 on June 23-24. A full attempt at an online Postgres conference across multiple days with multiple tracks.

???? – requires e-mail address or registration
???? – costs money to participate




ac

npm's CTO: So Long, and Thanks for All The Packages

#334 — April 16, 2020

Read on the Web

Node Weekly

npm Has Now (Actually) Joined GitHub — We announced GitHub’s acquisition of npm a month ago but now the process is complete. Not much real news here but the plan is to now focus on community engagement and improving registry infrastructure.

Jeremy Epling (GitHub)

Node v13.13.0 (Current) Releasedfs.readv is a new function to sequentially read from an array of ArrayBufferViews, util.inspect now lets you specify a maximum length for printed strings, the default maximum HTTP header size has been increased to 16KB, there are three new collaborators, and more.

Michaël Zasso

Get Better Insight into Redis with RedisGreen — Modern hosting and monitoring services include memory usage maps, seamless scaling, key size tracking, and more.

RedisGreen sponsor

▶  Watch the Live Coding of a New Feature for Node.js — This is not something for novices, but if the idea of watching ‘over the shoulder’ of a Node.js collaborator implementing a new feature directly into Node itself interests you.. this could be a valuable hour spent.

Vladimir de Turckheim

node-libcurl 2.1: libcurl Bindings for Nodelibcurl is a very powerful and well established way to fetch data from URLs across numerous protocols. node-libcurl 2.1.0 brings support for the latest version of libcurl (7.69.1) to us in the Node world.

Jonathan Cardoso Machado

npm's CTO: 'So Long, and Thanks for All The Packages!' — Ahmad Nassri was npm’s CTO but has now left. Here, he reflects on the past ten years of npm, the repo, the company, and the achievements of both.

Ahmad Nassri

???? Jobs

Find a Job Through Vettery — Vettery specializes in tech roles and is completely free for job seekers. Create a profile to get started.

Vettery

Node.js Developer at X-Team (Remote) — Join X-Team and work on projects for companies like Riot Games, FOX, Coinbase, and more. Work from anywhere.

X-Team

▶️ Get ready for your next role: Pluralsight is free for the entire month of April. Stay Home. Skill Up. #FreeApril — SPONSORED

???? Tutorials

Working With AWS Route 53 from Node — Route 53 is Amazon Web Services’ suite of DNS-related services. Like every AWS service, you can control it via an API, and here’s how to manipulate hosted zones from Node.

Valeri Karpov

Best Practices Learnt Running Express.js in Production for 4 Years — There’s a lot of stuff packed in here focused around middleware, testing, logging, and general concerns around scaling and keeping apps running in production.

Adnan Rahić

The Node.js Security Handbook — Improve the security of your Node.js app with the Node.js security handbook made for developers.

Sqreen sponsor

How To Set Up an Express API Backend Project with PostgreSQL — A pretty extensive walkthrough of creating an HTTP API using Express with Node.js and Postgres on the backend, then deploying it all on Heroku.

Chidi Orji

Porting to TypeScript Solved Our API Woes — From the guy behind the (in)famous Wat video comes a tale of porting a backend from Ruby to TypeScript.

Gary Bernhardt

How to Mass Rename Files in Node

Flavio Copes

▶  Let's Build a Digital Circuit Simulator In JavaScript — A special episode of the Low Level JavaScript series takes us on a brief journey into the world of digital logic.

Low Level JavaScript

The Story of How I Created a Way to Port Windows Apps to Linux — We mentioned ElectronCGI recently as a way to let .NET and Node.js code depend upon each other, but here its creator explains more about the how and why.

Rui Figueiredo

How to Create an Alexa Skill with Node — Implementing a custom ‘skill’ for Amazon Alexa by using Node and AWS Lambda.

Xavier Portilla Edo

???? Tools, Resources and Libraries

Node v10.20.1 (LTS) Released — If you’re still using Node 10, don’t use v10.20.0, use this, due to a bug in the .0 release.

Bethany Nicolle Griggs

emoji-regex: A Regular Expression to Match All Emoji-Only Symbols

Mathias Bynens

ip-num: A Library to Work with ASN, IPv4, and IPv6 Numbers — Happy in both Node and the browser.

dadepo

Optimize Node.js Performance with Distributed Tracing in Datadog

Datadog APM sponsor

verify-json: Verify JSON Using a Lightweight Schema — A lighter weight alternative to something like JSON Schema.

Yusuf Bhabhrawala

middle-manager: A Lightweight 'No BS' Presentation Tool — A bit of humor, really. It turns Markdown into basic presentations but then the magic is it detects your ‘BS’ business language so you can remove it ????

Anders




ac

Caddy 2.0 released, plus a little black hat Go

#311 — May 8, 2020

Unsubscribe  :  Read on the Web

Golang Weekly

Caddy 2: The Go-Powered Web Server with Automatic TLS — After over a year of redesign, Caddy 2 has a new architecture to v1. If you want a new HTTPS server that ‘just works’, Caddy is well worth a look IMO. Its lead creator, Matt Holt, answered lots of questions on this Hacker News thread about the release.

Caddy Web Server

Rek: An Easy HTTP Client for Go — The inspiration here is from Python’s very well known and highly esteemed Requests library.. so the Pythonistas among you might like this!

Luc Perkins

Modern Redis Features with RedisGreen — Online upgrades to the latest Redis 6.0 features, memory mapping, key size tracking, and more.

RedisGreen sponsor

Life Without Line Numbers — There’s a lot of buzz around reducing the size of Go binaries (1.15 does so by ~6%) and here’s another tactic: reduce the precision of the position information. The gain is 2-6%, depending on how far you take it.

Josh Bleecher Snyder

▶  Discussing Black Hat Go“Are you excited to learn about hacking and that?” Got an hour? Roberto Clapis, a security engineer at Google, and Tom Steele, a co-author of Black Hat Go, join the Go Time team to discuss security, penetration testing, and more.

Go Time Podcast

???? Jobs

Enjoy Building Scalable Infrastructure in Go? Stream Is Hiring — Like coding in Go? We do too. Stream is hiring in Amsterdam. Apply now.

Stream

Find a Job Through Vettery — Vettery specializes in tech roles and is completely free for job seekers. Create a profile to get started.

Vettery

???? Articles & Tutorials

Mid-Stack Inlining in Go — Inlining a function can lead to serious performance gains, so why not do it for everything? Well, there are always trade-offs.

Dave Cheney

Asynchronous Preemption in Go 1.14 — How the new preemption implementation works, including the use of a lesser-known signal (SIGURG).

Vincent Blanchon

Why Are My Go Executable Files Larger Than My Source Code? — We built a data visualization tool to find out. Here’s how we built it, and what we learned.

Cockroach Labs sponsor

Accelerating Aggregate MD5 Hashing Up to 800% with AVX512 — The culmination of this work is md5-simd, a Go library that performs such rapid MD5 hashing (when running concurrently). The use cases here are quite restricted but you may appreciate seeing how such things are implemented for any high end SIMD wrangling you need to do one day.

MinIO Blog

▶  A Beginner's Guide to gRPC in Go — There’s a written version of the tutorial if you dislike videos.

TutorialEdge

Four Steps to Daemonize Your Go Programs — Daemons are programs that run as non-interactive background processes (e.g. background job processors, Web servers, database systems).

Ilija Eftimov

Go as a Scripting Language? — There’s plenty of folks that use Go as a scripting language, but there are challenges around REPLs and shebang support. Some of these challenges are being addressed today.

Segio De Simone

???? Code & Tools

UUID 3.3: A Pure Go Implementation of UUIDs — A pure Go implementation of Universally Unique Identifiers (UUID) as defined in RFC-4122 covering versions 1 through 5.

The Go Commune

Reed-Solomon: A Reed-Solomon Erasure Coding Library — A Go port of a Java library built by Backblaze that does Reed Solomon erasure coding (a way to send or store data in a larger form that’s resilient to data loss). Boasts operation of over 1GB/sec per core.

Klaus Post

ko 0.5: Build and Deploy Go Apps on Kubernetes — ko’s objective is to “to make containers invisible infrastructure.” It’s been rapidly maturing in the past few months too.

Google

Monitor the Health and Performance of Your Golang Apps with Datadog APM. Free Trial

Datadog APM sponsor

Tengo 2.2: A Fast Embeddable Script Language for Go — Quite a mature project now and worth a look if you need to add some dynamic scripting to your code.

Daniel Kang

UniPDF 3.7: A Library for Creating and Processing PDF Files — Pure Go, which is neat, but note it’s dual licensed: AGPL for open source, commercial for closed source projects.

UniDoc

Mockery: A Mock Code Generator for Go Interfaces

Vektra

Dynamo: An Expressive DynamoDB Library

Greg Greg

???? Two Fun Side Projects

gasm: An Experimental WASM Virtual Machine for Gophers“I did this just for fun and for learning WASM specification.” Nonetheless, it works with basic examples.

Takeshi Yoneda

thdwb: A Homebrew Web Browser and Rendering Engine — Another experimental, fun learning project. You won’t be using it for your day to day browsing any time soon but projects like this keep the imagination fueled up.

Danilo Fragoso

It'd be quite cool to link to more fun Go experiments and side projects actually, so let us know if you work on any. Bonus points for games, musical, or Web experiences ????




ac

Ellie and Nele: From she to he - and back to she again

When two trans men fell in love they began to have second thoughts about their gender.




ac

Blasian love: The day we introduced our black and Asian families

Blasian - black and Asian - couples now exist in South Africa... but they don't always have an easy time.




ac

The rapper's track that sparked a wave of killings

Tensions have long existed between gangs in Tottenham and Wood Green - for 10 weeks in 2018 they boiled over.




ac

The actor who was really stabbed on stage

Conor Madden was playing Hamlet when a sword fight went badly wrong. Would he ever act again?




ac

Ex porn-star and activist explores men's rights issues

Philipp travels to a conference on men’s issues in Chicago, shedding light on the controversial movement.




ac

Virus vaccine research 'enormously accelerated'

A vaccine normally takes a decade to develop, but GSK and Sanofi want a viable coronavirus vaccine by the end of next year, GSK chief executive Emma Walmsley says.




ac

Coronavirus will have "significant impact" on economy

Chancellor Rishi Sunak has told reporters that Covid-19 will cause "hardship ahead".




ac

React Router & Webpack in Production

I’ve been working on a pretty large react-router codebase at work. Currently it has around 50~ code splits, which as you can imagine, is a lot of routes. This is going to be a post on the things I’ve learned throughout building out my development / production config and how we are using webpack in production.

###Initial Setup

Before I really dive into how my webpack config is setup and the problems I’ve found, I’ll quickly go over how this app is setup. Currently, there’s one entry point and it looks like this:

import React from 'react'
import { render } from 'react-dom'
import { match, Router, browserHistory } from 'react-router'
import AsyncProps from 'async-props'
import routes from '../routes/index'
/* globals document, window */

const { pathname, search, hash } = window.location
const location = `${pathname}${search}${hash}`

match({ routes, location }, () => {
  render(
    <Router
      render={props => <AsyncProps {...props}/>}
      routes={routes}
      history={browserHistory}
    />,
    document.getElementById('app')
  )
})

It looks like a standard react-router setup, except a couple things are different. For one, there’s way too many routes to have them all in this file, so we are importing the main route object into this file. Second, we are using match on the client side. Without matching first, the client side would try to render before the splits were downloaded causing an error. You can read a little more about match on the client here.

Next, we are using Ryan Florence’s awesome async-props library for loading data into components. It allows me to load data from an api before the server renders components. It will pass the data down to the client for the client-side render, and then data will load as you navigate to new pages automatically.

###Routes

Our main routes file looks like this:


export default {
  component: 'div',
  path: '/',
  indexRoute: require('./index'),
  childRoutes: [
    require('./login'),
    require('./account'),
    ...
  ]
}

There’s a lot more require’s in our app of course. And these are nested pretty deep. The files referenced in the root file have more child routes, and those use require.ensure which you can read about in the webpack docs on code splitting. It tells webpack to make a new bundle, and then load that bundle when require.ensure is called on the client. Here’s an example:

if(typeof require.ensure !== "function") require.ensure = function(d, c) { c(require) }

module.exports = {
  path: 'account',
  getComponent(location, cb) {
    require.ensure([], (require) => {
      cb(null, require('../../views/master/index.jsx'))
    })
  },
  childRoutes: [
    require('./settings'),
  ]
}

There’s a few things going on here. First, we have a function at the top that will polyfill require.ensure. Why? Well, on this project we are server rendering our whole site as well, which I would rather not do, but due to the type of site we are building: we have to. The next thing is the relative require path. I’m using this awesome babel resolver plugin along with webpack’s resolve paths so that I can import files like this:

import Header from '../../master/header'
//becomes
import Header from 'master/header'

Why do I have to use a babel plugin AND webpack’s resolve feature? Once again, doing a server rendered app, the code is ran on the server and also through webpack. In this particular app, I haven’t had time to experiment with webpacking the server. Anyways, if I didn’t use the babel plugin, errors would be thrown on the server, but webpack would work fine. This is one of the common things I have ran into while building this app.

Realizing some things need to be done slightly different on the server or client. You may still be wondering why I am referencing the component as a relative path in the above route example, and that’s because the babel plugin I’m using only works with import and not require. My route objects are the one place that I have these “nasty” looking paths.

##Webpack

I was prompted to make this article after tweeting this out:

A couple people wanted a better explanation as to what’s happening here. When I was first building my production webpack config, even after using all of these plugins:

new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js'),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
  compress: { warnings: false },
  comments: false,
  sourceMap: false,
  mangle: true,
  minimize: true
}),

My bundle looked like this:

That’s pretty huge if you think about it. And I’m not talking about the amount of bundles. I’m talking about the file size. After searching everywhere for a solution to get the bundle size down further, I found webpack’s AggressiveMergingPlugin. This thing is a life saver. As you may have seen from the tweet, the output turns into this:

Just having the main, vendor, and one other bundle brings the whole site under 1MB. I’m using the plugin to only merge files if the size reduction is more than 50%, which is the default.

People talk about code splitting in webpack and think it’s really amazing to load the JS for the page you’re on and nothing more. It sounds great. The problem is that the file size is immensely bigger. If someone more familiar with webpack has a better idea as to why this is, I’d like a better explanation. It isn’t feasable to keep the splits instead of merging them. This site is pretty large, with a lot of routes as you can tell from the screenshots. Codesplitting without merging would cause way more waiting on the client side every time you navigate to a new page. Even if the JS was heavily cached, the first time you hit these pages it will have to load a 300kb bundle for some of them.

##Caching

That takes us to caching. We are about a month away from publicly launching this site, so we haven’t setup the workflow for pushing updates through a cdn, but that will be the end result. For now, in my webpack config, my output object looks like this:

output: {
  path: __dirname + '/public/assets/js/[hash]/',
  filename: '[name].js',
  chunkFilename: '[id].js',
  publicPath: '/assets/js/[hash]/'
},

This is in the production config of course. This way I can cache the files and when I update the code, the hash will change and the browser won’t be caching the old code. I pass in the hash as an env variable at runtime to that the server has the correct path to the assets folder.

##Problems

There were a few big problems I came across while building out a server rendered app with dynamic routes. The first was page titles. How am I supposed to have the right title on the client and on the initial server render? Thankfully, Ryan has yet another solution. react-title-component solves this perfectly.

The next was, how do I hit an api, wait for the response on server render, load new data on route changes, and of course, do this at the component level. As I mentioned before, async-props solves this problem too. It will give you route info so that you can make requests based on things in the url.

The next problem is one that I haven’t fully solved. Webpack is getting really slow. It takes around 20 seconds on a maxed out macbook 15” to build code in production. On the server, it takes more like a minute! If I’m in development mode, it takes around 10 seconds to make the initial build, and sometimes it lags on building the splits on code change. If anyone has insight into this I would love to hear it.

This one goes along with the webpack one, and it is reloading the server. I haven’t tried to webpack the server but I hear doing so works great for this. I don’t think it would fix the problem with webpack being slow though, and in fact it would probably make it even slower.

##Folder structure

I almost forgot to throw this one in here! I’m really happy with the structure of this project. I have a views folder that has all of the same folders and file names as the routes folder. It makes it really easy to find things. These also correspond with the URL to the page. /account/settings will be in views/account/settings.jsx and routes/account/settings.js. The same is true for my tests folder.

##Conclusion

I hope this gave you a good glimpse at how webpack and react router work at a larger scale than you see most blog posts cover. If you have any questions or things that you would like me to talk about that I haven’t already, please leave a comment below and I will update this post! I’m sure that I forgot a few problems and tips writing this. I was thinking this would be a short post but it blew up on me!




ac

How to Make Your React Apps 15x Faster

Without any modifications, React is really fast as-is. There are, however, a few things that you can do to improve performance. While working at HelloSign, I discovered some quick fixes that made our apps incredibly snappy. With these simple changes, I was able to reduce render time from over 3000 milliseconds to less than 200 milliseconds.

Without any modifications, React is really fast as-is. There are, however, a few things that you can do to improve performance. While working at HelloSign, I discovered some quick fixes that made our apps incredibly snappy. With these simple changes, I was able to reduce render time from over 3000 milliseconds to less than 200 milliseconds.

Editor’s Note:

Check out our upcoming React University Workshops. Our next workshop, React 2016, will be held on April 23 at Microsoft Reactor in San Francisco and will offer a deep dive into creating modern Single-Page Applications (SPA) using React, Redux, React Router, Immutable.js, and Webpack. Also, if you’re interested in learning the basics about what it takes to be a Data Visualization Engineer, check out React and D3.

Introduction

HelloSign is a cloud-based electronic signature tool founded in 2010. As you can imagine, HelloSign is a very JavaScript-heavy codebase. A lot of client-side behavior is necessary to create a rich signing experience. Lately, we’ve moved much of our codebase toward React. In fact, in many places we’ve broken up our codebase into several single-page applications written in React.

Although the HelloSign team was happy with React’s performance before I initially joined the project, I quickly found some low-hanging fruit that could improve runtime speed. Here are the steps you should take to see similar improvements in your own applications.

Create a Baseline Performance Measurement

Before you begin, you should take a baseline measurement. Optimizations are meaningless if you can’t verify the results of your modifications.

Thankfully, Chrome has excellent developer tools to help. One, little-used feature of Chrome’s DevTools is the “Timeline” tool. It allows you to record and analyze all activity in your application. You can record interactions on the page, locate potential memory leaks, measure the total time it takes to perform a task, and identify areas of potential jank. Best of all, the results can be recorded for comparison with your final benchmark.

There’s actually a really awesome video on Chrome’s DevTools that goes into detail about the “Timeline” feature. You can view it here.

We chose to measure the time elapsed between the initial paint of our signer page to the final rendering of the entire page. The initial download of our bundles still needs some optimization, but we’re neither going to mess with nor measure this parameter. It’s fairly easy and consistent to test render time rather than trying to click areas around the page and trying to measure its performance in a repeatable way. Then, all we needed to do was to go to the signer page, open Chrome’s DevTools “Timeline” tab, and refresh the page.

As a side note, make sure that when performing this test, the “Paint” and “Screenshots” boxes are checked so that you can see what the user sees as the page is being rendered.

After all that, we determined that our rendering time from initial paint was a little over 3 seconds. Much too long. Luckily, there was little we had to do to make this quite a bit faster.

Set NODE_ENV to Production

This step is easy to get wrong, even if you are well-informed. React’s documentation provides an overview, but doesn’t provide many specifics. React has great developer warnings and error checking, but these are only intended for development; if you take a look at React’s source code, you’ll see a lot of if (process.env.NODE_ENV != 'production') checks. This is running extra code that is not needed by the end user, not to mention that calling process.env.NODE_ENV is extremely slow. For production environments, we can remove all this unnecessary code. Just keep in mind that you don’t want to do this in development because it will remove all those helpful developer warnings.

If you’re using Webpack, you can use DefinePlugin to replace all instances of process.env.NODE_ENV with 'production', and then use the UglifyJsPlugin to remove all the dead code that no longer runs. Here’s a sample setup that you might use:

// webpack.config.js
  ...
  plugins: [
    new webpack.DefinePlugin({
      // A common mistake is not stringifying the "production" string.
      'process.env.NODE_ENV': JSON.stringify('production')
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
  ...

React Constant and Inline Elements Transforms

React 0.14 introduced support for certain transpile time optimizations with Constant and Inline Element Babel Transforms. React Constant Elements treats JSX elements as values and hoists them to a higher scope. In other words, it hoists static elements and thereby reduces calls to React.createClass. React Inline Elements converts JSX elements into the object literals that they eventually return. Again, this minimizes the runtime calls to React.createClass.

The implementation is rather simple. We added our Babel configuration in our package.json file:

// package.json
  ...
  "babel": {
    "env": {
      "production": {
        "plugins": [
          "transform-react-constant-elements",
          "transform-react-inline-elements"
        ]
      }
    }
  },
  ...

Final Measurement / Conclusion

Lastly, you’ll want to run the benchmark again and compare it with that saved benchmark from before these optimizations. As you can see, the total runtime profile ends 200ms after initial paint! That’s 15 times faster!




ac

Playing With React and D3

D3 is great at data visualizations, but it manipulates the DOM directly to display that data. Rendering DOM elements is where React shines. It uses a virtual representation of the DOM (virtual DOM) and a super performant diffing algorithm in order to determine the fastest way to update the DOM. We want to leverage React’s highly efficient, declarative, and reusable components with D3’s data utility functions.

At this point, we can safely say that React is the preferred JavaScript library for building user interfaces. It is used practically everywhere and is almost as pervasive as jQuery. It has an API that is simple, powerful, and easy to learn. Its performance metrics are really impressive thanks to the Virtual DOM and its clever diff algorithm between state changes. Nothing, however, is perfect, and React too has its limitations. One of React’s greatest strengths is the ease with which it integrate third-party libraries, but some libraries, especially opinionated ones, are more difficult to integrate than others.

An extremely popular library that can be tricky to integrate with React is D3.js. D3 is an excellent data visualization library with a rich and powerful API. It is the gold standard of data visualizations. However, Because this library is opinionated about data, it is no trivial endeavour to get it to work with React. A few simple strategies permit these two libraries to work together in very powerful ways.

Editor’s Note: Check out our upcoming workshop, React and D3, a crash course in learning how to create data visualizations with these two in demand libraries. Reserve your spot now on Eventbrite and get 20% off admission. Learn more at the Eventbrite page

What is React?

React is an open-source JavaScript library for creating user interfaces that addresses the challenges of building large applications with data that changes over time. Originally developed at Facebook, it is now seen in many of the most commonly used web applications including Instagram, Netflix, Airbnb, and HelloSign.

React helps developers build applications by helping manage the application state. It’s simple, declarative, and composable. React is not a traditional MVC framework because React is really only interested in building user interfaces. Some have called it the “V(iew)” in MVC, but that’s a little misleading. React’s viewpoint is different. As application logic has reoriented toward the client, developers have applied more structure to their front-end JavaScript. We applied a paradigm that we already understood from the server (MVC) to the browser. Of course, the browser environment is very different from the server. React acknowledges that client-side applications are really a collection of UI components that should react to events like user interaction.

React encourages the building applications out of self-contained, reusable components that only care about a small piece of the UI. Other frameworks such as Angular also attempt to do this, but React stands out because it enforces a unidirectional data flow from parent component to child component. This makes debugging much easier. Debugging is the hardest part of application development, so while React is more verbose that other libraries or frameworks, in the end it saves a lot of time. In a framework like Angular’s, it can be hard to figure out where a bug is coming from: The view? The model? The controller? The directive? The directive controller? Data in Angular flows in many different directions, and this makes it hard to reason about that state of your application. In React, when there is a bug (and there will be!), you can quickly determine where the bug originated from because data only moves in one direction. Locating a bug is as simple as connecting the numbered dots until you find the culprit.

What is D3?

D3 (Data-Driven Documents) is a JavaScript library for producing dynamic, interactive data-visualizations. It’s fairly low level, and the developer has a lot of control over the end result. It takes a bit of work to get D3 to do what you want, so if you’re looking for a more prepackaged solution, you’re probably better off with highcharts.js. That said, it is fairly simple to pick up once you get the hang of it.

D3 does four main things:

  1. LOADS: D3 has convenient methods for importing data from CSV documents.
  2. BINDS: D3 binds data elements to the DOM via JavaScript and SVG.
  3. TRANSFORMS: data can be adjusted to fit your visual requirements
  4. TRANSITIONS: D3 can respond to user input and animate elements based on that input

Why Would We Want To Use React with D3?

D3 is great at data visualizations, but it manipulates the DOM directly to display that data. Rendering DOM elements is where React shines. It uses a virtual representation of the DOM (virtual DOM) and a super performant diffing algorithm in order to determine the fastest way to update the DOM. We want to leverage React’s highly efficient, declarative, and reusable components with D3’s data utility functions. Also, once we create a chart component, we can want to be able to reuse that chart with different data anywhere in our app.

How to use React and D3?

D3, like React, is declarative.D3 uses data binding, whereas React uses a unidirectional data flow paradigm. Getting these two libraries to work together takes a bit of work, but the strategy is fairly simple: since SVG lives in the DOM, let React handle displaying SVG representations of the data and lett D3 handle all the math to render the data.

Of course, we’ll have to make compromises. React is unopinionated and flexible, thereby allowing you to accomplish whatever needs to be done. Some tasks, like creating axes, are tedious. We can let D3 directly access the DOM and create. It handles axes well, and since we only need to create very few, this tactic won’t affect performance.

Let’s go through a simple example. I created a repository you can use to follow along here: playing-with-react-and-d3. You can follow in the unfinished directory and if you get stuck you can take a look at the finished directory.

Let’s generate a random list of X-Y coordinates and display them on a ScatterPlot chart. If you’re following the tutorial, a finished example is provided for you under the “finished” directory, but you can also follow along under “unfinished.” I’ve gone through the trouble of doing all the setup for you. The build will automatically be created from “unfinished/src/index.jsx”

Let’s start by creating a simple “Hello World!” React component. Create a file under “components” named “chart.jsx”

// unfinished/src/components/chart.jsx
import React from 'react';

export default (props) => {
  return <h1>Hello, World!</h1>;
}

This example is simple, but let’s go over the explanation anyway. Since we’re rendering a simple H1 with no state, we can just export a function that returns the HTML we expect. If you’re familiar with Angular or Ember, it might look weird to insert HTML directly into our JS code. On the one hand, this goes against everything we’ve learned about unobtrusive JavaScript. But on the other hand, it actually makes sense: we’re not putting JavaScript in our HTML, we’re putting our HTML into our JavaScript. React sees HTML and client-side JavaScript as fundamentally bonded together. They’re both concerned about one thing – rendering UI components to the user. They simply cannot be separated without losing the ability to see what your component is going at a glance. The great benefits of this approach is that you can describe exactly what your component will look like when it’s rendered.

Also, keep in mind that this is only possible with JSX, which translates HTML elements into React functions that will render the HTML to the page.

Now, let’s move on and mount our component to the DOM. Open up “index.jsx”

// unfinished/src/index.jsx
import './main.css';
import React    from 'react';
import ReactDOM from 'react-dom';
import Chart    from './components/chart.jsx';

const mountingPoint = document.createElement('div');
mountingPoint.className = 'react-app';
document.body.appendChild(mountingPoint);
ReactDOM.render(<Chart/>, mountingPoint);

You probably noticed a few things. You might be wondering why we’re requiring a CSS file. We’re using Webpack, which allows us to require CSS files. This is very useful when we modularize both our stylesheets and our JavaScript. We’re also creating a div in which we want to mount our React app. This is just a good practice in case you want to do other things on the page then render a React component. Lastly, we’re calling render on ReactDOM with 2 arguments, the name of the component and the DOM element we want to mount it on.

Now, let’s install all the dependencies by navigating to the unfinished directory and running npm i. Then, fire up the server with npm run start and go to localhost:8080

Awesome! We have rendered our first React component! Let’s do something a little less trivial now.

Let’s compose some functions that will create an array of random data points and then render a scatter plot. While we’re at it, we’ll add a button to randomize the dataset and trigger a re-render of our app. Let’s open up our Chart component and add the following:

// unfinished/src/components/chart.jsx
import React       from 'react';
import ScatterPlot from './scatter-plot';

const styles = {
  width   : 500,
  height  : 300,
  padding : 30,
};

// The number of data points for the chart.
const numDataPoints = 50;

// A function that returns a random number from 0 to 1000
const randomNum     = () => Math.floor(Math.random() * 1000);

// A function that creates an array of 50 elements of (x, y) coordinates.
const randomDataSet = () => {
  return Array.apply(null, {length: numDataPoints}).map(() => [randomNum(), randomNum()]);
}

export default class Chart extends React.Component{
  constructor(props) {
    super(props);
    this.state = { data: randomDataSet() };
  }

  randomizeData() {
    this.setState({ data: randomDataSet() });
  }

  render() {
    return <div>
      <h1>Playing With React and D3</h1>
      <ScatterPlot {...this.state} {...styles} />
      <div className="controls">
        <button className="btn randomize" onClick={() => this.randomizeData()}>
          Randomize Data
        </button>
      </div>
    </div>
  }
}

Since we want our component to manage it’s own state, we need to add a bit more code than was necessary for our previous “Hello World” stateless functional component. Instead of just a function, we’re going to extend React.Component and describe our component in the render() method. render() is the heart of any React component. It describes what our component is supposed to looks like. React will call render() on initial mount and on every state change.

Inside of render(), we are both rendering a scatter plot component as if it were an HTML element and setting some properties or “props”. The ... syntax is a convenient JSX and ES2015 spread operator that spreads the attributes of an array or object instead of doing all of that explicitly. For more information check out: JSX Spread Attributes. We’re going to use render() to pass our data and a style object that will be used by some of our child components.

In addition, we’re also rendering a button with an onClick event handler. We’re going to wrap this.randomizeData() with an arrow function and bind the value of this to our Chart component. When the button is clicked, randomizeData() will call this.setState() and pass in some new data.

Let’s talk about this.setState(). If render() is the heart of a React component, setState() is the brains of a component. setState explicitly tells React that we’re changing the state, thereby triggering a re-render of the component and its children. This essentially turns UI components into state machines.

Inside of setState(), we’re passing an object with data set to the randomDataSet(). This means that if we want to retrieve the state of our application, we need only call this.state.whateverStateWereLookingFor. In this case, we can retrieve the randomData by calling this.state.data.

A little side note on how React works: React offers great performance for rendering UI components by implementing a diff algorithm and comparing a virtual DOM in memory with the actual DOM. When you think about it, the DOM is really a large tree structure. If there’s one thing we have learned from decades of computer science research, it’s how to compare and manipulate trees. React takes advantage of clever tree diffing algorithms, but in order to work, each component can only render one parent element (i.e., you cannot render sibling elements). That’s why In the render function we’re wrapping all our elements in one parent div.

Let’s get started with the scatter plot component. Create a file unfinished/src/components/scatter-plot.jsx :

// unfinished/src/components/scatter-plot.jsx
import React        from 'react';
import d3           from 'd3';
import DataCircles  from './data-circles';

// Returns the largest X coordinate from the data set
const xMax   = (data)  => d3.max(data, (d) => d[0]);

// Returns the highest Y coordinate from the data set
const yMax   = (data)  => d3.max(data, (d) => d[1]);

// Returns a function that "scales" X coordinates from the data to fit the chart
const xScale = (props) => {
  return d3.scale.linear()
    .domain([0, xMax(props.data)])
    .range([props.padding, props.width - props.padding * 2]);
};

// Returns a function that "scales" Y coordinates from the data to fit the chart
const yScale = (props) => {
  return d3.scale.linear()
    .domain([0, yMax(props.data)])
    .range([props.height - props.padding, props.padding]);
};

export default (props) => {
  const scales = { xScale: xScale(props), yScale: yScale(props) };
  return <svg width={props.width} height={props.height}>
    <DataCircles {...props} {...scales} />
  </svg>
}

There’s a lot going on here, so let’s start with the stateless functional component that we’re exporting. D3 uses SVG to render data visualizations. D3 has special methods for creating SVG elements and binding data to those elements – but we’re going to let React handle that. We’re creating an SVG element with the properties passed in by the Chart component and which can be accessed via this.props. Then we’re creating a DataCircles component (more on that below) which will render the points for the scatter plot.

Let’s talk about D3 scales. This is where D3 shines. Scales takes care of the messy math involved in converting your data into a format that can be displayed on a chart. If you have a data point value 189281, but your chart is only 200 pixels wide, then D3 scales converts that value to a number you can use.

d3.scale.linear() returns a linear scale. D3 also supports other types of scales (ordinal, logarithmic, square root, etc.), but we won’t be talking about those here. domain is short for an “input domain”, i.e., the range of possible input values. It takes an array of the smallest input value possible and the maximum input value. range on its own is the range of possible output values. So in domain, we’re setting the range of possible data values from our random data, and in range we’re telling D3 the range of our chart. d3.max is a D3 method for determining the maximum value of a dataset. It can take a function which D3 will use to give the max values of the X and Y coordinates.

We use the scales to render the data circles and our axes.

Let’s create the DataCircles component under unfinished/src/components/data-circles.jsx

// unfinished/src/components/data-circles.jsx
import React from 'react';

const renderCircles = (props) => {
  return (coords, index) => {
    const circleProps = {
      cx: props.xScale(coords[0]),
      cy: props.yScale(coords[1]),
      r: 2,
      key: index
    };
    return <circle {...circleProps} />;
  };
};

export default (props) => {
  return <g>{ props.data.map(renderCircles(props)) }</g>
}

In this component, we’re rendering a g element, the SVG equivalent to a div. Since we want to render a point for every set of X-Y coordinates, were must render multiple sibling elements which we wrap together in a g element for React to work. Inside of g, we’re mapping over the data and rendering a circle for each one using renderCircles. renderCircles creates an SVG circle element with a number of properties. Here’s where we’re setting the x and y coordinates (cx and cy respectively) with the D3 scales passed in from the scatter plot component. r is the radius of our circle, and key is something React requires us to do. Since we’re rendering identical sibling components, React’s diffing algorithm needs a way to keep track of them as it updates the DOM over and over. You can use any key you like, as long as it’s unique to the list. Here we’re just going to use the index of each element.

Now, when we look at our browser, we see this:

We can see our random data and randomize that data via user input. Awesome! But we’re missing a way to read this data. What we need are axes. Let’s create them now.

Let’s open up ScatterPlot.jsx and add an XYAxis component

// unfinished/src/components/scatter-plot.jsx

// ...

import XYAxis       from './x-y-axis';

// ...

export default (props) => {
  const scales = { xScale: xScale(props), yScale: yScale(props) };
  return <svg width={props.width} height={props.height}>
    <DataCircles {...props} {...scales} />
    <XYAxis {...props} {...scales} />
  </svg>
}

Now, let’s create the XYAxis component;

// unfinished/src/components/x-y-axis.jsx
import React  from 'react';
import Axis   from './axis';

export default (props) => {
  const xSettings = {
    translate: `translate(0, ${props.height - props.padding})`,
    scale: props.xScale,
    orient: 'bottom'
  };
  const ySettings = {
    translate: `translate(${props.padding}, 0)`,
    scale: props.yScale,
    orient: 'left'
  };
  return <g className="xy-axis">
    <Axis {...xSettings}/>
    <Axis {...ySettings}/>
  </g>
}

For simplicity’s sake, we’re creating two objects which will hold the props for each of our X-Y axes. Let’s create an axis component to explain what these props do. Go ahead and create axis.jsx

// unfinished/src/components/x-y-axis.jsx
import React from 'react';
import d3    from 'd3';

export default class Axis extends React.Component {
  componentDidMount() {
    this.renderAxis();
  }

  componentDidUpdate() {
    this.renderAxis();
  }

  renderAxis() {
    var node  = this.refs.axis;
    var axis = d3.svg.axis().orient(this.props.orient).ticks(5).scale(this.props.scale);
    d3.select(node).call(axis);
  }

  render() {
    return <g className="axis" ref="axis" transform={this.props.translate}></g>
  }
}

Our strategy up to this point has been to let React exclusively handle the DOM. This is a good general rule, but we should leave room for nuance. In this case, the math and work necessary in order to render an axis is quite complicated and D3 has abstracted that pretty nicely. We’re going to let D3 have access to the DOM in this case. And since we’re only going to render a ma




ac

Routing in React Native with Jake Murzy

Jake Murzy has been hard at work creating a new navigational library for React Native over the last couple of months. While React JS has the benefit of the highly-regarded React Router, such a comprehensive routing solution doesn’t exist yet in the React Native community. In fact, React Native’s routing landscape has been in constant upheaval for the last year. The library itself has official three ‘navigators’ for handling decision making on which components to show the user, including ‘NavigatorIOS’, ‘Navigator’, and - more recently - ‘NavigatorExperimental’. The open source community likewise has the packages ‘React Native Router Flux’, ‘React Native Router Native’, and ‘React Native Redux Router’, which of which are in various states of completion, or, more commonly, disrepair.

Jake Murzy has been hard at work creating a new navigational library for React Native over the last couple of months. While React JS has the benefit of the highly-regarded React Router, such a comprehensive routing solution doesn’t exist yet in the React Native community. In fact, React Native’s routing landscape has been in constant upheaval for the last year. The library itself has official three ‘navigators’ for handling decision making on which components to show the user, including ‘NavigatorIOS’, ‘Navigator’, and - more recently - ‘NavigatorExperimental’. The open source community likewise has the packages ‘React Native Router Flux’, ‘React Native Router Native’, and ‘React Native Redux Router’, which of which are in various states of completion, or, more commonly, disrepair.

React Router Native appears to focus on matching the API of the immensely popular React Router package, even going as far as introducing the concept of a URL into React Native, which bucks the notion that only web applications need or deserve a URL.


Today Jake is going to share some of his thoughts about his new library.

Q: Hi Jake! The React Native library contains several navigation solutions and the surrounding ecosystem has multiple routing libraries. What made you decide to make your own?

Hey! Thanks for reaching out. I’ve been eagerly watching what’s happening with navigation on React Native for a while. Until very recently, the whole Navigation scene in React Native was a mess. Navigator was being deprecated in favor of NavigationExperimental and NavigationExperimental wasn’t ready for prime time.

My team was just starting a new project so I tried quite a few of the available solutions. Having successfully used React Router on the web, we were looking for a similar solution. Unfortunately, React Router did not support React Native, and other solutions we found were either very unstable, had a hard time keeping up with upstream changes on each release or the quality of code was quite poor.

NavigationExperimental did most of what we wanted but it was a bit too low level so often times we found ourselves writing navigation related code and you can imagine how this gets tedious fast. The low level nature of NavigationExperimental is really by design to allow abstractions to be built up in higher layers. So to finally answer your question, the project came directly out of my frustration trying to make navigation work on React Native as good as React Router did on the web.

Q: What is the strength of your routing system? Is there any type of app that would be a perfect fit with React Router Native? Conversely, is there any type of app that wouldn’t be a good fit with the library?

The use cases for React Router Native is pretty much the same as NavigationExperimental—which is the only supported navigation library by the React Native team. React Router Native is a very thin layer on top of NavigationExperimental that offers React Router’s mental model in a native app. Under the hood, it uses React Router for routing and NavigationExperimental for rendering user components. This is a very powerful combination that makes URLs possible on mobile.

Most apps do not have deep-linking capabilities because implementing it for each screen in your app is a challenging task. Even within apps, users are often forced to take screenshots to share information. And for many, it’s vital that their apps support deep-linking. For example, Yelp goes as far to show a share prompt when users take screenshots of business listings. React Router Native enables developers to implement deep-linking in their apps without putting forth much effort. This can pave the way for a more connected app ecosystem.

That being said, we’re still in the early days of React Native figuring out the right abstractions. Navigation on mobile is a challenging task, and having different flavors is only healthier as the community weighs the pros and cons of each approach rather than second guessing best-practices. So I’m hoping to get the community involved to shape the direction of the project.

Q: Is React Router Native designed to be used with any of the official Navigation components written by the React Native team?

Absolutely. One of the primary goals of the project is that we follow React’s “learn once, write anywhere” principle. So you can use the community maintained components, interpolators and pan responders from React Native, and everything is highly customizable if you need instruct NavigationExperimental to do fancy transition animations, etc.

Q: The React Router team has somewhat famously rewritten their API several times in the last two years, each time introducing several breaking changes. Do you hope to keep your library at parity with React Router, breaking changes and all? Case in point, the V4 release of React Router will introduce an all-new API.

React Router v4 is a complete rewrite. There was a lot of head-scratching on Twitter over the entire new set of breaking changes. Many people thought v4 should at best have been released under a different name. I’m not sure if I agree with that sentiment though, I understand where it is coming from. React Router v4 is a preview release, and in my opinion, it’s really hard to argue against replacing a foreign API with simple React components. I do hope to keep the library at parity with React Router, and to be honest, v4’s new everything-is-a-component approach makes the integration even easier. So over the next few weeks I’ll be working on v4 support.

Q: If you were new to React Native, which routing solution would you use? Why?

This is a hard one to answer. Eric Vicenti has done a great job on NavigationExperimental and most of the issues have been sorted out by the community over the last few months. So if you’re familiar with Redux concepts and comfortable writing your own reducers to manage navigation state, NavigationExperimental is a great choice.

One that I’m surprised you didn’t mention that deserves more attention is ExNavigation—another fairly new addition to the brewery. It also uses NavigationExperimental and is maintained by Adam Miskiewicz, Brent Vatne and other awesome members of the Exponent community. It feels a bit tied to the Exponent platform, but runs perfectly fine on React Native and is open source. So you’ve got that.

Finally, If you’re just getting started with React Native and all you need is to be able to click a button and have it transition to a different scene but you don’t want it to get in your way when you need to reach in and apply complex navigational patterns, I strongly recommend you take React Router Native for a spin.




ac

Leveraging React for Easy Image Management

React is a good tool when it comes to building flexible and reusable UI components. However, it’s “one of those libraries” that cannot handle all the tasks involved in building a full fleshed UI project. Other supporting tools - such as a recently announced React SDK from Cloudinary - are available to provide solutions that the React core cannot.

In such cases where media (images and videos) becomes a heavy task to handle, Cloudinary simplifies the process with the new React SDK. Let’s build and image library with Cloudinary and React using the Cloudinary’s React SDK.

Prerequisites

The only requirements for using Cloudinary in your existing React project are to install the React SDK and the upload widget. If you do not have an existing React project and want to try these examples, take the following steps:

1. Install Dependencies

We need a minimal amount of dependencies so we can focus on building a media library and not structuring a React app:

{
  "name": "img-library",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "watch": "webpack -d --watch",
    "build": "webpack",
    "serve": "serve ./public"
  },
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "babel-core": "^6.18.2",
    "babel-loader": "^6.2.9",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "serve": "^1.4.0",
    "webpack": "^1.14.0"
  },
  "dependencies": {
    "axios": "^0.15.3",
    "cloudinary-react": "^1.0.1",
    "react": "^15.4.1",
    "react-dom": "^15.4.1"
  }
}

React (and React DOM) must be used since we are making a React app. The cloudinary-react dependency is Cloudinary’s React SDK, which we will soon see how it works. axios is a tool for making HTTP requests and, in our case, we will use it request images from the Cloudinary server.

# Install dependencies
npm install

2. Setup Webpack

Webpack is our build tool. Only minimal settings are required to have a build running and our React app compiling:

// ./webpack.config.js
var webpack = require('webpack');
var path = require('path');

var BUILD_DIR = path.resolve(__dirname, 'public');
var APP_DIR = path.resolve(__dirname, 'src');

var config = {
    entry: APP_DIR + '/index.jsx',
    output: {
        path: BUILD_DIR,
        filename: 'bundle.js'
    },
    module : {
        loaders : [
            {
                test : /.jsx?/,
                include : APP_DIR,
                loader : 'babel'
            }
        ]
    }
};

module.exports = config;

Basic configuration - an entry, output and loaders to handle the React .jsx files.

3. Entry Points

We need to create an entry point, as we specified in the Webpack configuration, and another entry point for the browser, which is an index.html file:

// ./src/index.jsx
import React, { Component } from 'react';
import { render } from 'react-dom';

class Main extends Component {
    render() {
        return (
           <div className="main">
               <h1>Scotchage</h1>
           </div>
        );
    }
}

render(<Main />, document.getElementById('container'));
<!-- ./public/index.html -->
<html>
<head>
    <!--Stylesheet-->
    <link rel="stylesheet" href="style.css">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <!--Container for React rendering-->
    <div id="container"></div>
    <!--Bundled file-->
    <script src="bundle.js"></script>
</body>
</html>

4. Create Cloudinary Account

You need a Cloudinary account to continue with these examples. Sign up for free and store your credentials safely as shown on the dashboard:

Uploading Images

Before using the React SDK to deliver images from the Cloudinary servers, let’s use the awesome Cloudinary upload widget to upload images. First, we need to add this widget to our index.html:

<!-- ./public/index.html -->
<html>
<head>
   . . .
</head>
<body>
    . . .
    <!-- UPLOAD WIDGET -->
    <script src="//widget.cloudinary.com/global/all.js" type="text/javascript"></script>
    <script src="bundle.js"></script>
</body>
</html>

Next, we create a button, attach an event to it and upload an image once the button is clicked:

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

class Main extends Component {

    uploadWidget() {
        cloudinary.openUploadWidget({ cloud_name: 'CLOUD_NAME', upload_preset: 'PRESET', tags:['xmas']},
            function(error, result) {
                console.log(result);
            });
    }
    render(){
        return (
            <div className="main">
                <h1>Galleria</h1>
                <div className="upload">
                    <button onClick={this.uploadWidget.bind(this)} className="upload-button">
                        Add Image
                    </button>
                </div>
            </div>

        );
    }
}

render(<Main />, document.getElementById('container'));

The uploadWidget member method is the handler invoked by the click event to handle our image upload by calling cloudinary.openUploadWidget. openUploadWidget takes a config object and the upload callback handler. The config object must have at least cloud_name and upload_preset properties with valid values. You can read more about Cloud Names and Upload Presets.

Delivering Images with SDK

The Cloudinary React SDK has three major components, Image, CloudinaryContext and Transformation:

  • Image: This component is responsible for the actual delivery of images. It takes the image ID and asks the server for this image. When the image is provided, it is also responsible for painting the image on the browser.
  • Transformation: This component is used to apply transformations to images delivered with Image.
  • CloudinaryContext: You can specify Cloudinary configuration for each image on the Image component. This can be tedious when you are dealing with multiple images. CloudinaryContext allows you to apply configuration to a group of Images.

Most times you would end up with a structure like this:

<CloudinaryContext>
    <Image>
        <Transformation />
        <Transformation />
    </Image>
    <Image>
        <Transformation />
    </Image>
</CloudinaryContext>

Back to our demo app, we can request an image from the Cloudinary server and display it with the following components:

import React, { Component } from 'react';
import axios from 'axios';
import { CloudinaryContext, Transformation, Image } from 'cloudinary-react';
import { render } from 'react-dom';

class Main extends Component {
    constructor(props) {
        super(props);
        this.state = {
            gallery: []
        }
    }
    componentDidMount() {
    // Request for images tagged xmas       
axios.get('http://res.cloudinary.com/christekh/image/list/xmas.json')
            .then(res => {
                console.log(res.data.resources);
                this.setState({gallery: res.data.resources});
            });
    }
    uploadWidget() {
       // . . .
    }
    render(){
        return (
            <div className="main">
                <h1>Galleria</h1>
                <div className="gallery">
                    <CloudinaryContext cloudName="CLOUDNAME">
                        {
                            this.state.gallery.map(data => {
                                return (
                                    <div className="responsive" key={data.public_id}>
                                        <div className="img">
                                            <a target="_blank" href={`http://res.cloudinary.com/christekh/image/upload/${data.public_id}.jpg`}>
                                                <Image publicId={data.public_id}>
                                                    <Transformation
                                                        crop="scale"
                                                        width="300"
                                                        height="200"
                                                        dpr="auto"
                                                        responsive_placeholder="blank"
                                                    />
                                                </Image>
                                            </a>
                                            <div className="desc">Created at {data.created_at}</div>
                                        </div>
                                    </div>
                                )
                            })
                        }
                    </CloudinaryContext>
                    <div className="clearfix"></div>
                </div>
            </div>

        );
    }
}

render(<Main />, document.getElementById('container'));

Take one more look at the upload code:

 cloudinary.openUploadWidget({ cloud_name: 'christekh', upload_preset: 'idcidr0h', tags:['xmas']},
            function(error, result) {
            . . .

Each image is tagged with xmas, which serves as a way to request images with this tag as a collection. This is exactly what we are using the axios library to do when the component mounts:

axios.get('http://res.cloudinary.com/CLOUDNAME/image/list/xmas.json')
            .then(res => {
                console.log(res.data.resources);
                this.setState({gallery: res.data.resources});
            });

axios uses promises, so whenever the promise resolves in our case, we have a payload of images. We take advantage of React state to update our UI with the fetched resources.

Down to rendering, we configure the CloudinaryContext with our cloud_name, iterate over the gallery state that stores the images and displays them using the Image component. We also apply few transformations using the Transformation component.

For security reasons, Cloudinary will not allow you to make such request from the client unless you tell it to. The best way to go is to use the admin API via a backend SDK and then send the resource list to the client.

Updating State with New Uploads

We are able to upload images and request for images to be displayed on the user’s browsers. Here is how we update the displayed images instantly when the user uploads a new image:

uploadWidget() {
        let _this = this;
        cloudinary.openUploadWidget({ cloud_name: 'CLOUDNAME', upload_preset: 'PRESET', tags:['xmas']},
            function(error, result) {
            // Update gallery state with newly uploaded image
                _this.setState({gallery: _this.state.gallery.concat(result)})
            });
    }

Rather than logging the uploaded image information to the console, we update the gallery state, which bears the list of requested images, by concatenating the uploaded result to the gallery.

Image Management Simplified

Image uploads, transformation and delivery has never been easier. These tasks have been a serious challenge for developers. Cloudinary has created a way to abstract all this hard work, enabling you to simply plug and play.




ac

The Diverse React Navigation Ecosystem

The routing ecosystem around React and React Native is quite different. One is characterized by a strong incumbent, and the other is plagued by rapid change.

React JS

No question about it, React Router (ReactTraining/react-router) is king here. They have the benefit of several years of active development, along with an active community submitting PR’s, fixes, etc. Supplement that with myriad tutorials and how-to’s and you end up with a well-supported, stable product. To be fair, React Router has suffered some major API upsets, and is nearly the poster-child for javascript fatigue but the maintainers have declared their lasting support for a few specific versions, which means you can plop down with V3 and be good to go for the next 12 to 24 months.

React Native

Ok, this is where things start to get really, really crazy. The most important thing to keep in mind is that the React Native team has produced three navigation helpers: NavigatorIOS, Navigator, and NavigatorExperimental.

  • NavigatorIOS was quickly deprecated, as it was supported only by (you guessed it) IOS.
  • Navigator is the currently endorsed solution for navigation, at least if you are following the official docs. However, its about to be upset by-
  • NavigationExperimental. This is an updated navigator that has learned some lessons from Navigator, and has some solid integration with Redux. ‘Navigator’ is (or was!) sleighted to be deprecated in favor of NavigationExperimental at some point.

Already you have three ‘official’ navigators supported by the React Native team. The big issue with all three of these is that they are somewhat lightweight and don’t include a lot of common navigation situations out of the box, like sidebars, tab bars, headers, etc. To solve that, the community has introduced…

  • React Native Router Flux (aksonov/react-native-router-flux). My personal favorite, this is router is based upon NavigationExperimental. You can imagine that the authors looked at NavigationExperimental, realized that everyone would be writing the same wrapper code around it, and so created this project.
  • React Native Router (t4t5/react-native-router). Haven’t used it, but it is colossally popular.
  • React Router Native (jmurzy/react-router-native). Strives for API conformity with React Router (the above mentioned one). The great approach here is that they bring in the concept of a URL in native apps, where one doesn’t otherwise exist. This is a great approach that simplifies a lot of common routing situations. Of course, there’s one more big solution that is supposedly going to become the standard:
  • React Navigation (react-community/react-navigation). Seen as a solution that will soon be ‘official’ in the community, it is intended to replaced NavigationExperimental. This package is still in active development, so I expect at least a bit of API upset over the coming months. If you want to use official solutions, go with this, if you want a tried and true solution, go with React Native Router Flux.




ac

Component Kits for React Native

You won’t find as many styling solutions for React Native as you will for React JS. This stems from two simple realities:

  1. React Native is a much smaller target for component libraries than traditional CSS frameworks. In other words, Bootstrap CSS can be used with any web framework, whereas component libraries for React Native only work with…you guessed it…React Native.
  2. Customizing React Native styling isn’t the easiest thing in the world. Many apps demand custom styling, which makes component kits not too useful. In addition, it is challenging to customize each and every component, as the flexibility that you gain with traditional CSS on the web doesn’t carry over easily to component libraries.

With that said, here are a few options.

You won’t find as many styling solutions for React Native as you will for React JS. This stems from two simple realities:

  1. React Native is a much smaller target for component libraries than traditional CSS frameworks. In other words, Bootstrap CSS can be used with any web framework, whereas component libraries for React Native only work with…you guessed it…React Native.
  2. Customizing React Native styling isn’t the easiest thing in the world. Many apps demand custom styling, which makes component kits not too useful. In addition, it is challenging to customize each and every component, as the flexibility that you gain with traditional CSS on the web doesn’t carry over easily to component libraries.

With that said, here are a few options.

NativeBase - Essential cross-platform UI components for React Native

A huge collection of components, most of which look quite nice. That’s the plus side. The down side is that some of the components are somewhat buggy. No offense to the library authors, its just the state of the library - it needs a bit of work. For example, here’s an issue I opened a few days ago when I discovered the swipe deck component crashed when only a single data element was provided: DeskSwiper throws on single element lists · Issue #562 · GeekyAnts/NativeBase. The authors fixed it up awfully fast, but, hey, that’s a bug that seems like it could have been caught earlier.


React Native Elements - react-native-community/react-native-elements

This is my personal favorite. The styling is generally platform agnostic; it won’t look out of place using it on either Android or iOS. Each component has simple customization, the docs are solid, and it comes with a good set of icons. This is a no-brainer.


React Native Material Design - react-native-material-design/react-native-material-design

Another solid choice, but mostly only useful for Android. Again, its a bit unsettling to see material design - traditionally a stable of Android devices - on iOS. Besides that, the docs are still a work in progress, as evidenced by the lack of docs for nearly half of the components. Nonetheless, if you’re looking for a material design solution, this is better than nothing. It is also worth noting that the project looks generally unmaintained.


React Native Material Kit - xinthink/react-native-material-kit

Another material design solution, but much better maintained than React Native Material Design. This one has the added benefit of a nicer customization API for creating your own custom components - see the docs on this. It also has some more dynamic components like progress bars and sliders, which you may not see on other frameworks. Anything that helps save you time to build your app is always a solid benefit.


Do Your Own Styling!

If none of these choices float your boat, you can always learn how to style components from scratch yourself. I have a course on Udemy that will teach you how to make perfectly reusable components for your own projects. Check it out here: The Complete React Native and Redux Course - Udemy




ac

2006 Club World Cup Final: Internacional 1-0 Barcelona

Internacional-Barcelona, FIFA Club World Cup Japan 2006 Final: The powerful side of Ronaldinho, Deco and Andres Iniesta lost out to the Brazilians despite creating a number of chances.




ac

2007 Club World Cup Final: Boca Juniors 2-4 AC Milan

In the final of the FIFA Club World Cup Japan 2007, Italian giants AC Milan got two goals from 'Pippo' Inzaghi and one each from Kaka and Alessandro Nesta to become the world's top team.




ac

Coach of Brazil, Carlos Amadeu arrives at the stadium

KOLKATA, INDIA - OCTOBER 28: Coach of Brazil, Carlos Amadeu arrives at the stadium prior to the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

The Mali team is pictured prior to the FIFA U-17 World Cup India 2017 3rd Place match

KOLKATA, INDIA - OCTOBER 28: The Mali team is pictured prior to the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Coach of Brazil, Carlos Amadeu arrives at the stadium

KOLKATA, INDIA - OCTOBER 28: (EDITOR'S NOTE: This image has been processed using digital filters). Coach of Brazil, Carlos Amadeu arrives at the stadium prior to the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Coach of Mali, Jonas Komla arrives at the stadium

KOLKATA, INDIA - OCTOBER 28: (EDITOR'S NOTE: This image has been processed using digital filters). Coach of Mali, Jonas Komla arrives at the stadium prior to the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Coach of Mali, Jonas Komla arrives at the stadium

KOLKATA, INDIA - OCTOBER 28: Coach of Mali, Jonas Komla arrives at the stadium prior to the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Lincoln (R) of Brazil battles for the ball with Ibrahim Kane and Boubacar Haidara of Mali

KOLKATA, INDIA - OCTOBER 28: Lincoln (R) of Brazil battles for the ball with Ibrahim Kane and Boubacar Haidara of Mali during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

Paulinho of Brazil and Fode Konate of Mali in action

KOLKATA, INDIA - OCTOBER 28: Paulinho of Brazil and Fode Konate of Mali in action during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Lincoln of Brazil battles for the ball with Boubacar Haidara and Mamadi Fofana of Mali

KOLKATA, INDIA - OCTOBER 28: Lincoln (R) of Brazil battles for the ball with Boubacar Haidara and Mamadi Fofana of Mali during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

Lincoln of Brazil battles for the ball with Boubacar Haidara and Mamadi Fofana of Mali

KOLKATA, INDIA - OCTOBER 28: Lincoln (R) of Brazil battles for the ball with Boubacar Haidara and Mamadi Fofana of Mali during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

Goalkeeper of Brazil, Gabriel Brazao in action

KOLKATA, INDIA - OCTOBER 28: Goalkeeper of Brazil, Gabriel Brazao in action during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Coach of Mali, Jonas Komla during the FIFA U-17 World Cup India 2017 3rd Place match

KOLKATA, INDIA - OCTOBER 28: Coach of Mali, Jonas Komla during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Players of Mali pose for photos during the FIFA U-17 World Cup India 2017 3rd Place

KOLKATA, INDIA - OCTOBER 28: Players of Mali pose for photos during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Goalkeeper of Brazil, Gabriel Brazao in action

KOLKATA, INDIA - OCTOBER 28: Goalkeeper of Brazil, Gabriel Brazao in action during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Lincoln of Brazil battles for the ball with Boubacar Haidara of Mali

KOLKATA, INDIA - OCTOBER 28: Lincoln of Brazil battles for the ball with Boubacar Haidara of Mali during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

Brenner of Brazil battles for the ball with Boubacar Haidara of Mali

KOLKATA, INDIA - OCTOBER 28: Brenner (R) of Brazil battles for the ball with Boubacar Haidara of Mali during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

Lincoln of Brazil battles for the ball with Boubacar Haidara of Mali

KOLKATA, INDIA - OCTOBER 28: Lincoln of Brazil battles for the ball with Boubacar Haidara of Mali during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

brahim Kane of Mali reacts during the FIFA U-17 World Cup India 2017 3rd Place match

KOLKATA, INDIA - OCTOBER 28: Ibrahim Kane of Mali reacts during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

A general view of action during the FIFA U-17 World Cup India 2017 3rd Place match

KOLKATA, INDIA - OCTOBER 28: A general view of action during the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Players of Brazil celebrate after the FIFA U-17 World Cup India 2017 3rd Place

KOLKATA, INDIA - OCTOBER 28: Players of Brazil celebrate after the FIFA U-17 World Cup India 2017 3rd Place match between Brazil and Mali at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Philip Foden of England and Juan Miranda of Spain in action

KOLKATA, INDIA - OCTOBER 28: Philip Foden of England and Juan Miranda of Spain in action during the FIFA U-17 World Cup India 2017 Final match between England and Spain at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Coach of England, Steve Cooper looks on

KOLKATA, INDIA - OCTOBER 28: Coach of England, Steve Cooper looks on prior to the FIFA U-17 World Cup India 2017 Final match between England and Spain at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Head coach Santiago Denia of Spain looks on

KOLKATA, INDIA - OCTOBER 28: Head coach Santiago Denia of Spain looks on during the FIFA U-17 World Cup India 2017 Final match between England and Spain at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

Philip Foden of England reacts

KOLKATA, INDIA - OCTOBER 28: Philip Foden of England reacts during the FIFA U-17 World Cup India 2017 Final match between England and Spain at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

George McEachran of England battles for the ball with Cesar Gelabert of Spain

KOLKATA, INDIA - OCTOBER 28: George McEachran (L) of England battles for the ball with Cesar Gelabert of Spain during the FIFA U-17 World Cup India 2017 Final match between England and Spain at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

George McEachran of England battles for the ball with Cesar Gelabert of Spain

KOLKATA, INDIA - OCTOBER 28: George McEachran (C) of England battles for the ball with Cesar Gelabert of Spain during the FIFA U-17 World Cup India 2017 Final match between England and Spain at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

Tashan Oakley-Boothe of England and Sergio Gomez of Spain in action

KOLKATA, INDIA - OCTOBER 28: Tashan Oakley-Boothe of England and Sergio Gomez of Spain in action during the FIFA U-17 World Cup India 2017 Final match between England and Spain at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

Head coach Steve Cooper of England gives a gift for coach Santiago Denia of Spain

KOLKATA, INDIA - OCTOBER 28: Head coach Steve Cooper of England gives a gift for coach Santiago Denia of Spain during the FIFA U-17 World Cup India 2017 Final match between England and Spain at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

Morgan Gibbs White of England and Cesar Gelabert of Spain in action

KOLKATA, INDIA - OCTOBER 28: Morgan Gibbs White of England and Cesar Gelabert of Spain in action during the FIFA U-17 World Cup India 2017 Final match between England and Spain at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Tom Dulat - FIFA/FIFA via Getty Images)




ac

George McEachran celebrates with the trophy

KOLKATA, INDIA - OCTOBER 28: George McEachran celebrates with the trophy after winning the FIFA U-17 World Cup India 2017 Final match between England and Spain at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)




ac

George McEachran celebrates with the trophy

KOLKATA, INDIA - OCTOBER 28: George McEachran celebrates with the trophy after winning the FIFA U-17 World Cup India 2017 Final match between England and Spain at Vivekananda Yuba Bharati Krirangan on October 28, 2017 in Kolkata, India. (Photo by Buda Mendes - FIFA/FIFA via Getty Images)