ReactJS Patterns: Compound Components

React patterns have advanced and grown, you can now follow multiple approaches to rendering a component. One such pattern is the Compound Component.

Have you ever been in the position that you need to render multiple components that share the same state in multiple places? For example let’s build out a input component that has a label. Both components respond to validation. Let’s build a very basic example.

We have an App component which will render a Input which responds to validation. Below is the code for  InputWithValidation:

As we can see above we have a component that renders a span and a input tag, when the input is changed it performs some validation and updates the isValid state value. This is fine however what if we want to change how this is rendered. For some reason we want to have the label below the input. We could hack a solution to the existing code to handle this. We could add an additional prop to InputWithValidation which sets the placement of the label.

So now we are checking if the position is top then rendering before the input or checking of position is bottom and rendering after the input. This works but is hacky and is hard to maintain. For example if we add a sub label we need to then repeat the process for it. This is where the compound component pattern comes into play. It allows the consumer to use the component how they wish to use it.

We can see now that we have access to the inner components and are able to arrange the display logic how we with. However these components are still fully aware of the parent state of theInputWithValidation component. But how is this built inside theInputWithValidation component?

 

First we need to add some static properties to theInputWithValidation class. These properties are actually functional React components, they are functional as all data they need will be passed as props.

 

We can see that the two static properties are components that deconstruct the isValid prop, the span also takes the children to allow for the customer label. The input takes the change prop to allow the validation to be performed. These get passed in via the render method below:

 

The render method returns the value of mapping over each child and cloning the child then passing new props to the child with isVald and change. We use the React children API as it provides methods that can interact with the Reach Children opaque data structure. We then use React.cloneElement which clones and return a new React element using the current element as the starting point. The resulting element will have the original element’s props with the new props merged in shallowly. This allows use to add additional props to the children passed from the parent container.

 

This provides us with a extendable and customisable component that the consumer can restructure and mold as they wish.

 

PropType Utils

Introducing prop-type-utils

I recently build a react development utils package and thought I would share my reasons and how I build this package.

 

Why?

The React prop-types package provides a standard array of checks for your React component props. These include basic checks for JavaScript primitives such as Number, String, Function etc. You can even define complex objects and enum like values. As show below:

PropTypes also allows you to set if a prop is required, this will display a warning message in the browser console when this prop has not been provided. Note this only happens in development mode. This can help developers understand required props for components, its very useful when the component you are using has no or little documentation.

 

However there could be a case when you need to link props, e.g. if you have a Modal component that has a isOpen prop which is required and a name prop which only exists when the model is open. The name is required also but only really needed when the modal is open. prop-type-utils to the rescue, using the custom prop type function you can create your own PropType checks.

 

How?

PropTypes provides a custom function PropType, this allows you to write your own checks. The check function takes the component props, the prop name and the component name. As show below:

As you can see when preforming the check you can return a Error if the check fails, else return nothing. From this I decided to build out my own utils.

PropType Utils

Prop Type Utils is a collection of useful prop type validation rules.

isEven

isGreaterThan

isLessThan

isBetween

includes

isRequiredWhen

 

jscodeshift and codemods

JS Code Shift

JS Code shift is a toolkit for running codemods, codemods are transforms that take existing code file(s) and produces new code. That is a codemod in the simplest form. I like to think if them as find and replace script on steroids. JS code shift created by Facebook provides 2 things:

  • Runner: The runner executes the transform scripts and provides feedback on the files changed
  • A wrapper for recast, recast is a AST-to-AST tool. Recast is used to preserve the style and syntax of the code that was transformed.

The pattern for running a codemod is to provide the transform path then path to the file(s) that you wish to transform.

 


jscodeshift -t path-to-codemod path-to-code 

 

You can also provide additional options to help with the process e.g. -d for a dry run if you want to test without making changes. -p to print detailed info on the process. JS Code Shift provides an API for transforms

 


module.exports = function(fileInfo, api) {
  return api.jscodeshift(fileInfo.source)
    .findVariableDeclarators('foo')
    .renameTo('bar')
    .toSource();
}

This example taken from the repo, shows how you can easily replace all occurrences of a foo variable with bar. The above transform get passed the file and the JS Code Shift API. This is then used to get the file source and from here there are methods to get different parts of the file e.g. findVariableDeclarators.

 

CodeMods

JS Code Shift provides an extremely powerful toolkit but the true power lives in the code mods that have been created.  I have managed to find some from quick googling, the reactjs community repo holds a collection react code mods. With react being a fast paced and evolving library code mods really help to evolve an existing code base to new patterns and methodologies. Pattern changes such as React.render to ReactDOM.render, in react 0.14 the render method was moved to the react-dom package. Instead of manually changing all your files you could use the code mod. Other code mods are provided such as  manual-bind-t0-arrow which replaces all manuall function binding to use ES6 arrow functions which scopes the functions.

Code Mods are not only just for react they can be run on any JavaScript code, such as a code mod to help migration to ES6. Removing all var’s and replacing with let or const can be a challenge when you have a large code base but running a code mod makes the process quick and painless.

Taking old ES5 code using var’s

Running the codemod:

Resulting code:

We can see here that the codemod has checked the code and determined that the new source should have one let and two const’s.  However nothing is ever perfect and we could say that the const for myObj should be a let, although the code is still technically valid.

 

You can find more codes mods in the following repos:

 

5 Common/Uncommon JavaScript Mistakes

JavaScript is a very powerful language, as we all know “With great power comes great responsibility”

Original post

Working with JavaScript 364 days a year (Yes I do take Christmas day off), has resulted in many mistakes. We all make mistakes, below is a list of the 5 mistakes I can think of off the top of my head.

1: “this”

“this” is probably the most powerful and dangerous feature of JavaScript. The this context in JavaScript can allow developers to save time and effort to build powerful functions. At the same time it can cause a priority 1 defect in your application.


this.foo = 'foo';

document.querySelector('.my-div').onclick = function() {
  console.log(this.foo)
}
//Logs undefined

document.querySelector('.my-div').onclick = function() {
  console.log(this.foo)
}.bind(thid);
//Logs 'foo'

As you can see above the “this” context is not always what you expect.  The reason in the above example “this” is not foo is due to the scoping of the event handler. The event handler has its own “this” context. You can use bind to change the this context however with the use of ES6/ES2015 arrow functions you can control the scope of “this”.


this.foo = 'foo';

document.querySelector('.my-div').onclick = () => {
  console.log(this.foo)
}

2: Global Events

This is probably the least used and seen mistake however I have seen it and it cost me time debugging a error. IE and Chrome both expose a global event variable “Window.event”. This at first look this already looks bad as anything global is a code smell. Also the fact that only two browsers provide this should be a put off.


onClick: () => {
  console.log(Window.event);
}
//Bad 

onClick: (event) => {
  console.log(event);
}
//Good

3: Function Scope

Similar to “this” issues, function scope can cause problems at later stages. The most common and simple example of this is using timeouts inside a loop statement.


for (var i = 0; i < 5; i++) {
    setTimeout(function () {
        console.log(i);
    }, 1000);
}

However this can be overcome by using function binding:


for (var i = 0; i < 5; i++) {
    setTimeout(console.log.bind(this, i), 1000);
}

4: Object Equality


const chris1 = {
   name: 'Chris',
   location: 'Belfast'
}

const chris2 = {
   name: 'Chris',
   location: 'Belfast'
}

console.log(chris1 === chris2); //false
console.log(chris1 == chris2); //false

The reason for this is that internally JavaScript has two different approaches for testing equality. Primitives like strings and numbers are compared by their value, while objects like arrays, dates, and plain objects are compared by their reference. That comparison by reference basically checks to see if the objects given refer to the same location in memory. As we have created two different const variables they resided in two different blocks of memory. This can be tested using assignment by reference.


const chris1 = {
   name: 'Chris',
   location: 'Belfast'
}

const chris2 = {
   name: 'Chris',
   location: 'Belfast'
}

console.log(chris1 === chris2); //false
console.log(chris1 == chris2); //false

const chris3 = chris2;
console.log(chris3 == chris2); //true

You can use libraries like lodash to do object equality.

5: string.replace

By default string.replace does not work globally. When using string replace and the first case is matched it will stop. This will work for most cases when you know there is only one instance to replace. however when replacing items in a large string you will need to use the global flag.


const myString = "This string has many spaces";
console.log(myString.replace(/ /,""));
//"Thisstring has many spaces"
console.log(myString.replace(/ /g,""));
//"Thisstringhasmanyspaces"

 

If you liked this list you can see more common JavaScript in the great post by Ryan J. Peterson in the Toptal post 10 Most Common JavaScript Mistakes

 

Monitor events with monitorEvents Chrome console

In my free time (usually waiting for tests to complete or webpack to compile) I like to check API documentation. The other day I was looking through the Chrome Developers tools API docs and I stumbled across the monitorEvents.

Using the monitor events method allows you to watch all or chosen events triggered on a target. A simple example of this is listening to the document body:


monitorEvents(document.body, 'click');

Then clicking on the page generates the below output:

Screen Shot 2016-07-10 at 19.31.44

The event gives some useful information such as:

  • clientx – the x point from where the click was triggered
  • clienty – the y point from where the click was triggered
  • srcElement – the source of the click, this is the DOM element from where the click was triggered, useful when trying to follow a path of events that have been triggered.

The above is just for a click event however other events such as scroll, mouseover etc will return more information on user or application interactions.

A real world usage for monitorEvents would be when debugging a page and trying to determine if a DOM node was getting events triggered on it that you did not expect or you want to find the route of the events. In some cases a third party plugin might trigger scroll or mouse events on DOM elements that you want to keep control of.

Of Course when you want to stop listening to events you can use unmonitorEvents(document.body); to stop the monitoring.

 

ES7 Pipe Proposal

I was recently listing to an episode of JavaScript Air at the end of the show durning the picks Kent C Dodds mentioned the pipe operator. This was the first I had heard of the pipe in JavaScript. After some digging I found some interesting information on the proposal.

The pipe operator allows you to chain functions together is a clean and simple syntax. Currently there are a few standard methods for chaining functions.

1. Using pure functions and wrapping each function:


const removeSpace = (word) => {
    return word.replace(' ', '');
}

const capitalize = (word) => {
    return word.toUpperCase();
}

const reverse = (word) => {
    return word.split("").reverse().join("");
}

const result = reverse(capitalize(removeSpace('hello world'))); //DLROWOLLEH

As you can see over time the complexity of the wrapping functions will increase the maintenance effort.

2. Using a chaining function from a popular library such as lodash or underscrore.


//These must be added to the lodash mixins 
const removeSpace = (word) => {
    return word.replace(' ', '');
}

const capitalize = (word) => {
    return word.toUpperCase();
}

const reverse = (word) => {
    return word.split("").reverse().join("");
}
_.mixin({
    removeSpace: removeSpace,
    capitalize: capitalize,
    reverse: reverse
});


const result =  _.chain('hello world').removeSpace().capitalize().reverse().value(); //DLROWOLLEH

This is maintainable however requires the addition of a third party dependency which you might not want. It also requires you to pollute the lodash namespace.

The proposed pipe operator allows you to achieve the same as above but in a much clean and more maintainable method. The issue with the two current methods are maintenance or dependence on others. If and when the pipe makes it into the standard then it removes any dependency and the clean syntax it’s easy to read and maintain. The below example shows:


const result = "hello word"
                |> removeSpace
                |> capitalize
                |> reverse;
//DLROWOLLEH

Now when an extra processing function is to be added its just another line with the “|>” pipe operator. This (to me at least) gives a clear picture of whats going on. Developers that have used bash before will recognize the “|” as a pipe for pushing data into another command or process. The arrow gives a clear direction, this can also support more complex functions.


const result = "hello word"
                |> _ => removeSpace('test', _)
                |> capitalize
                |> reverse;
//DLROWOLLEHTSET

The underscore is a ref to the initial param that’s being passed to the functions, this lets you pass other params or even mimic currying.

I can imagine there will be a lot more examples this can be used for and I’m looking forward to seeing this getting into the Es2016 spec. You can see more about the pipe operator here.

 

ES6 Features

I have been using ES6/ES2015 for a few months in my full time job. Its been a gradual adoption process taking on the new features as and when we see fit. Over these months I have built up a list of my new goto patterns for JavaScript taking advantage of ES6.

Const & Let

Let

One of the biggest changes with ES6 is the addition of const and let. Let provides a means to define variables inside block scope. This can help to combat the existing hoisting problems with JavaScript.

// ES5
if (foo === 'foo')
   console.log(bar);
   var bar = 'bar'
   console.log(bar);
}

In the above example var will be hoisted and could potentially cause issues with the code.

// ES6
if (foo === 'foo')
   console.log(bar);
   let bar = 'bar'
   console.log(bar);
}

In the let example the variable will still be hoisted however the referencing of the variable will be done in the block before hand. This means that when running the ES5 code you will just see an undefined message for the first console. However in the let case you will get a reference error indicating that you have tried to use a var before it has been declared.

Const

Const provides a way to create a constant that is either global or local scoped. When defining a constant you must provide a value as the value cannot be changed later.

// define MY_CONST as a constant and give it the value 7
const MY_CONST = 7;
// this will fail silently
MY_CONST = 20;
// will print 7
console.log("my CONST is: " + MY_CONST);
// trying to redeclare a constant throws an error 
const MY_CONST = 20;
// the name MY_CONST is reserved for constant above, so this will also fail
var MY_CONST = 20; 
// MY_CONST is still 7
console.log("my CONST is " + MY_CONST);

There is some controversy around const as it’s not what some people might expect for example the code below will not throw an error:

const MY_CONST = {foo: 'bar'}
MY_CONST.foo = 'test'
console.log(MY_CONST) // Object {foo: "test"}

An alterative to const would be to use Object.freeze()

Arrow Functions

Arrow function provide a cleaner syntax for the standard function expression and it also binds the lexical this scope to the function. This not only makes the code look clean but also takes away the pain of scope binding. No more var that = this also all arrow functions are anonymous. You can use arrow functions in a number of ways:

 //ES6
(param) => { statements }
(param) => expression
param => { statements }
// A function with no parameters requires parentheses or an underscore:
() => { statements }
_ => { statements }

Spread

The spread operator provides a cleaner way of dealing with arguments or params for function. This becomes very useful when working with React and JSX as the below example shows:

var params = {foo: 'bar', bar: 'foo'};
//Without spread
<MyElement foo={params.foo} bar={params.bar} />

//With spread
<MyElement {...params}/>

In both examples the JSX element is getting the foo and bar params, the second is cleaner and also reduced the maintenance of the code. As the params object grows you do not need to update the JSX element declaration.

Parameter Destructuring

Parameter destruction is one of the gems I have found recently. It allows you to clean up the code when you know what you need from a param. An example of this would be a using a promise/async or callback function that returns you a result. In a lot of cases you only need one part of the response. You can now define what you want and ignore the rest.

//Without param destructuring
myfunction((err, result) => {
    if (!err) {
        console.log(result.body);
    }
});

//With param destructuring
myfunction((err, {body}) => {
    if (!err) {
        console.log(body);
    }
});

One gotcha I have found with this is when the code is transplied, when Babel transpliles the code it looks like this:

//Transplied
myfunction((err, _ref) => {
    var body = _ref.body;
    if (!err) {
        console.log(body);
    }
});

If the result param is undefined or null this will fail at run time, causing an unexpected error. This has caught me out before when the expected result was not defined and only failed while in production.

Object Literals

Last but not least Object literals. This is another clean syntax which I have been using alot. It provides a shortcut to defining variables.

var foo = 'bar';
var test = { foo };
console.log(test.foo); // 'bar';

This can also work when exporting modules, we have all seen the code below before:

function plus() {
    ....
}

function subtract() {
    ...
}

function total() {
    ....
}

module.exports = {
    plus: plus,
    subtract: subtract,
    total: total
};

This follows the revealing module pattern and is okay but we could use object literals to clean this up.

module.exports = { plus, subtract, total };

It’s a small change but reduces bulk and provides a clean and simple syntax to read.

That’s all for now

This is just a few examples of what I have been using but I’m still building up my list of ES6 features and hoping to get into some ES7 features soon. If you know of any other great features drop a comment.

 

Should You Commit Compiled Code?

Working on a Java project you would never dream of committing a built war or jar file, so when working with JavaScript why would you think of committing the compiled source. So many projects I have worked on have by default commit the dist/lib code. This adds bloat and unnecessary steps to committing and merging such as making sure that you build before committing files and that you build when merging.

Preventing Commits of Complied Code

When setting up a new project always create a .gitignore file and add this to the project. For most projects I have worked on we have always used a dist/lib folder for the compiled source. For these cases add the following to your .gitignore.

# compiled source
dist
lib

if you have already committed the dist or lib you can stop tracking the files by using the following git command: git rm -r –cached

How to Provide Users with the Compiled Source

The easiest and most recommended (personal opinion) method for distributing your source is via npm. Npm allows you to publish code to a central repository and allow users to quickly access and use the code. The reason that I prefer Npm over other package managers like bower is due to the Npm repository, the repository allows publishers to push only the needed content so that users only pull down and have access that what they need. Bower however acts more like a link to git repositories which in turn requires publishers to commit complied source.

NPM Publish

To publish to Npm you can follow some simple steps that will have you pushing code in no time.
Create your npm account. You can also pay to have private repositories and push/get from these.
– Add the name field to the package.json file in your project.
– Add a prepublish task to the npm scripts
– Run npm publish

You can see an example file below:

{
  "name": "module-name",
  "version": "10.3.1",
  "description": "An example module to illustrate the usage of a package.json",
  "author": "Your Name ",
  "scripts": {
    "test": "echo 'No Tests'",
    "start": "node index.js",
    "prepublish": "uglifyjs --compress --mangle input.js"
  },
  "main": "dist/foo.js",
......

You can either have a build task that you call from the prepublish or just call the build commands. Now when you run npm publish the prepublish will run and compile your source. Now you need to make sure that only this gets pushed to the Npm repository. This can be achieved by using a .npmignore similar to the .gitinore however this will list all your project content except for the dist/lib folders.

Now your project is setup to only publish and track what users need and want.

 

SMACSS: Scalable and Modular Architecture for CSS

I have been working a lot recently with CSS and updating application styles.

I have always followed the simple pattern of placing all CSS in one file (stlye.css). However when I started started working with SASS I started to break up the styles into logical files, each file folding the styles for a page or a section of a page. This still ended led to issues are the file would grow and I would usually end up with reproduced styles and when it came to removing a style it was hard to trace.

SMACSS

SMACSS is a style guide you can follow that will provide more organisation for your css. Its promoted as not a framework but a way to examine your design process. SMACSS is broken up into a number of categories:
– Base
– Layout
– Module
– State
– Theme

Each of these categories can be used to structure the css of a project.

Base

Base styles are styles that will cover the whole project. Root document styles such as the body text, links styles and anything else that can cover the whole project.

body {
    margin: 0;
    padding: 0;
    font-family: "Bell MT", BellMT, Garamond, Georgia, “Times New Roman”, Times, serif;
    line-height: 1.5;
    color: #333;
}
a {
  color: #039;
}

We can see from the example above that we are setting the font for the document and also setting the links colours. Anything that is not specific to a part of the application can be added to your base.

Layout

Layout as you can guess takes responsibility for the layout of the document. The layout would contain the styles for blocks on the page such as a nav bar, header, main content area and a footer. The layout file could look something like:

nav {
  width: 20%;
  float: left;
},
main {
  width: 80%
  float: left;
}
footer {
  width: 100%
}

Here we can see the different sections of the application.

Modules

Modules are used to store the different parts of the application, If you page has blog posts on it and each post has a preview. This is a module you can contain the styles for that module in a file named preview.css. You can also extend modules and have submodules.

State

State rules are ways to describe a our module or layout will look when in a particular state. Is it hidden or expanded? Is it active or inactive? They are about describing how a module or layout looks on screens that are smaller or bigger. They are also about describing how a module might look in different views like the home page or the inside page.

Theme

Themes are similar to state in that the can describe how a part of the page looks. However different to state the theme can be used to change to look of the page based on a user preference.

Why SMACSS

So you know what SMACSS can do for your css but why should you use it. When working on large scale JavaScript applications it is common to break up the code into manageable areas such as modules or use a MVC style structure. Why not apply the same to css, when multiple developers are working on code things can get messy. Merge conflicts, code duplication and complexity can and will happen unless some rules are introduced. With SMACSS you can break down the css into manageable chunks and allow for developers to work together with little to no issues.

To learn more about CSS architecture, layout and best practices in writing and managing CSS layouts, check out the CSS Layout Tutorial from Toptal.

 

CSS Flexbox

Flexbox is a CSS property that aims to provide a better method to page layout that the currently popular methods using floats. I recently came across Flexbox when working on CSS bug. I preformed the usual Stackoverflow search and blindly copied and pasted the answer into my code. As expected everything work, but why? What was tis Flexbox I was seeing?

I decided to look into Flexbox and here is a very basic overview of how to use Flexbox. Flexbox is an alternative was to control page layout, without the need for floats. Floats have there own advantages and disadvantages. The main idea behind Flexbox is the ability for the container element to dynamically alter the size of its child elements. This leans it use towards responsive design as it will work to fill the container area as best as possible.

The example below shows a container div with 5 children, the container has flex as is display while the children all have flex:1 set.

See the Pen ojXvBd by Chris Laughlin (@chrislaughlin) on CodePen.

Note that each child is of equal height and width and all work to fill the parent container. This is the power of Flexbox, there is no need to set any width or height of the container or the children. Also note that the flex:1 of the child is does not effect the layout. This will be applied to each child and will be come more clear in the next example.

See the Pen pjJzzv by Chris Laughlin (@chrislaughlin) on CodePen.

You can see from the above example box 2 is bigger this is because we have set it with a higher flex than the others. So now box 2 is two times the size than the others. This can be done for any of the boxes just by changing the flex value. So on that thought you could potentially make a 3 column layout (that was all the rage back in the day) by setting the flex of the middle column and you get responsive design for free.

See the Pen zvGOYN by Chris Laughlin (@chrislaughlin) on CodePen.

Browser Support

Now for the bad part, there is currently not full browser support for Flexbox, currently Chrome, Firefox, Safari, IE (11), Opera and Android (4.4.4+) have full support. Other browsers require you to add a prefix however if you are using SASS or LESS you could use a mixin to achieve this.