Posts

Showing posts from September, 2017

ES6 and React.js: Pass props to components using comment-like code

Comments usually help you, but they can lie. Sometimes that lie will lead you down a wild goose chase to find something that doesn't exist. The JavaScript engine cannot validate comments so they have to always be taken at face value. Use them only when you need to. Luckily, ES6 brings some nice features to cleanly avoid comments when passing props into components. Let's look at a small example. Not all of data in our ParentComponent gets passed into UserProfile, its child component. But at the same time, we want to make our code as readable and expressive as possible. There are multiple ways to approach this. import React, { Component } from 'react' // ParentComponent props // this.props = { // name: 'Andrew', // description: 'A person', // imageUrl: 'http://www.somewebsite.com/profile_picture.jpg', // age: 26, // height: '180cm', // birthday: '10.18.1990', // favoriteColor: 'blue', //

Equality in JavaScript

JavaScript's use of equality is, objectively, counterintuitive. But there is some method to the madness. In its own way, it makes sense (mostly). But it can not be inferred. You have to learn it. Type coercion with == The thing that everyone hates. So what is type coercion? Type coercion is what happens when you ask JavaScript to compare something that is sort-of-kind-of might be true. The list of rules are massive. Numbers can turn into strings; null turns into 0; booleans convert to numbers; This monstrosity of "logic" with null and 0. You can sit down and learn all of the rules if you hate yourself. But the more convenient option is to just never use == Strict equality with === This is equality with zero type coercion. Much better. JavaScript's strict equality properly compares primitives For primitives, comparisons are very straightforward. They are compared by its value, because

Arrow functions, context and why they're so important in React.js

An unintuitive concept, but these are fundamentally different &ltbutton onClick={this.runFunction}//&gt //NOT THE SAME &ltbutton onClick={() => this.runFunction()}//&gt Try it out yourself later in a component, where this.runFunction uses this.setState . The first will throw an error. The other will not. Theres a short explanation and a long one. To someone who has no idea why these two are different, I think a long explanation is in order. function and its this play by its own rules The defintion of context in a function does not obey lexical scoping unless you tell it to. If you give it no declarations, it assumes this is the window object. Strict declaration of context this.myFunction // 'this' is my context, where my 'this' resulting declaration will obey lexical scoping function ConstructorExample() { this.testAnonThis = function() { //this.testThis binds this function to my constructor's cont

I solved my most difficult problem and shared my solution with npm

I was having trouble making image rendering tidy and clean in a project I'm currently brushing up on. I solved it using a component as a wrapper that controls render based on whether or not all images were loaded inside the wrapper's children. I couldn't find any solutions online so I published it to npm. Its name is react-on-images-loaded. Check out my demo and see how you like it. It's a more versatile version of my original solution. It's okay if you hate it and uninstall. You might run into problems as well. If either of those happen, kindly take the time to tell me what's happening or send me the hateful message here ! :) It was shocking easy to make my own package In the same way create-react-app makes setting up a React.js app a breeze, generator-react-component exists for anyone looking to publish their own npm package. Note that you hav

The power of iterators in ES6

Symbols  were quietly added to ES6. As a web developer, they have low use cases. But Symbol.iterator , embedded into certain object types, give developers access to ES6s new iterator. The for...of  loop This new loop is similar to .forEach  for arrays, but the main difference is that for...of loops can be used on anything with a Symbol.iterator attribute. for (let char of "console.logged character by character") { console.log(char); } new String()[Symbol.iterator] ? true : false // true new Array()[Symbol.iterator] ? true : false // true new Set()[Symbol.iterator] ? true : false // true new Map()[Symbol.iterator] ? true : false // true This means strings, maps , sets , and arrays are all iteratable using for...of loops. Array.from for objects that have a Symbol.iterator Array.from is essentially a "mapped" version of what a for...of loop does. Array.from("string") //['s', 't', 'r', 'i', 'n', 'g&

Parent referencing using ampersand (&) in Sass

Turns out reference selectors, and nesting in general, is a debatable paradigm to use. But for styles that are closely related and/or act on the same html elements, it can be a clever way to DRY up your code and keep things tidy. Hover effects are a great example. But I think the best one I've used so far is with visible and hidden transitions in my web apps. Sass reference selector syntax .hidden { animation-timing-function: cubic-bezier(0.1, 0.8, 0.1, 1.000); transition: opacity 500ms ease-in-out; &-true { @extend .hidden; opacity: 0; } &-false { @extend .hidden; opacity: 1; } } Compiles down to CSS .hidden, .hidden-true, .hidden-false { animation-timing-function: cubic-bezier(0.1, 0.8, 0.1, 1); transition: opacity 500ms ease-in-out; } .hidden-true { opacity: 0; } .hidden-false { opacity: 1; }

Contrasting var and ES6s new declarations: let and const

let and const are two new declaration types in JavaScript, which have the ability to completely replace var declaration. To use them effectively, and understand why they can be a direct replacement, it's important to understand how they work. var is function scoped. It is hoisted and initialized at the top var , regardless of where it is assigned, will become declared and initialized at the beginning of the function. This means that any variable you declare will be available everywhere inside the function. This process is referred to as hoisting. Hoisted variables with var are declared and initialized at the top of the function, but have no value All variables that are declared and initialized with var are initialized as undefined . They have no value until you reach the line of code that assigns it a value. const undefinedConsoleLog = _ => { console.log(sadlyUndefined) //undefined var sadlyUndefined = 'declared by var, und

Using arrow functions for stateless React.js components

Stateless is good. It's a fundamental strength of functional programming. React components are class based, but basic components, that don't need a state, can be written as an arrow function. Why stateless Stateless components are predictable because they do not have their own this variable that can be sneakily manipulated in a function. An arrow function's this is inherited from the scope above it. If you are making a component that doesn't use any React.js features (aside from jsx), you can probably turn it into an arrow function component. Less overhead, less lines and more predictable behavior. Class-based component import React, { Component } from 'react' class ProfilePicture extends Component { render() { return ( &ltdiv&gt &ltimg src={this.props.imageUrl}/&gt {this.props.name} {this props.userDescription} &lt/div&gt ) } }

Promises in parallel using async/await and Promise.all

ES7 brings async/await which, for the most part, replaces promise chains for asynchronous function calls. But the ES6 promise object still has some fancy tricks up its sleeves that can't be abstracted out. If promises dont rely on each other, run them in parallel Use Promise.all like a synchronous "checkpoint". await Promise.all It accepts an array of promises and only returns a value after all promises are resolved. This means you can pass in promises that are currently running that will always resolve before the subsequent lines of code are run. Sample Promises const sendText = text => { return new Promise(function(resolve, reject) { setTimeout( _ => resolve(text), 2000) }) } const chainText = (prevText, newText) => { //relies on value from sendText return new Promise(function(resolve, reject) { setTimeout( _ => resolve(prevText + newText), 2000) }) } Must be synchronous cons