The best left-handed mouse you can buy in 2020

Original Source: http://feedproxy.google.com/~r/CreativeBloq/~3/SMXb6mg2nSU/best-left-handed-mouse

Looking for the best left-handed mouse can be difficult, as even in 2020, many mouse makers seem to neglect southpaws and churn out loads of right-handed mice, and hardly any for lefties.

This can be incredibly frustrating, as the humble mouse is one of the most important peripherals we use when interacting with our computers. For creatives, it's especially important to find a mouse that's comfortable to use, and for left-handed people, that can sometimes be a struggle.

This is where our guide to the best left-handed mice can help. We've collected the best mice for left-handed users, and listed them right here, so you can easily find the best one for your needs. 

Not all of these mice are designed just for lefties. Many of them are ambidextrous in design, so they can be comfortably used in any hand, and you'll still be able to reach every button. You'll notice that some mice on this page come with plenty of additional buttons. These can be configured to help speed up your workflow, and help you be even more productive. Of course, we also have left-handed mice that favour simplicity, and so still with that tried-and-tested two-button design. 

For more ambidextrous options, take a look at our main buying guide to the best mouse in 2020.

Left-handed mouse: the best options available now

Logitech G903 Left

The Logitech G903 is a wireless gaming mouse that does it all. Thanks to 11 programmable buttons and up to 12,000 DPI of accuracy, this left-handed mouse offers more than most could even use. The mechanical button tensioning (which gives you physical feedback through the button clicks) lets you personalise it exactly. Even more useful are the five profiles you can switch between – adjust settings like sensitivity and button uses to enable you to hop between designing, browsing, and gaming uses. Wireless charging using the PowerPlay mat is another great feature that makes that 32-hour battery life even less of a worry. You can leave the lighting on, lowering battery to 24-hours of use, without worry.

SteelSeries Sensei Ten

If you're after a left-handed gaming mouse, then your options are limited, but the good news is that many mouse makers are now embracing ambidextrous designs, which means their mice are comfortable to use for both left- and right-handed people. SteelSeries is one of those manufacturers, and the Sensei Ten combines a left-hand-friendly design with a brilliant sensor that makes it fast and accurate to use. There's loads of customisation options, and it comes with a Tilt Tracking feature, which keeps tracking your movements even when you’re lifting your mouse and putting it back down at tilted angles.

Microsoft Bluetooth Mobile Mouse 3600

The Microsoft Bluetooth Mobile Mouse 3600 is the best left-handed mouse for people on a budget. It's compact and affordable, but crucially, it's well built as well. It's ideal for people who travel a lot and want a dependable wireless mouse that they can easily carry around.

Its ambidextrous design means it's a great choice for left-handed users as well. Microsoft has a formidable reputation when it comes to peripherals, and the Microsoft Bluetooth Mobile Mouse 3600 is a great example of this.

Mad Catz Rat 1

The Mad Catz Rat 1 is a wired mouse that's impressive to look at but somehow remains low in price. The quirky aesthetic is functional too, as the design means the mouse can be adjusted to fit any hand for perfect ergonomic comfort. There are only three buttons, but that keeps this mouse light for travel (it can even be split to make it more compact). With multiple colour options and a very low price, this is a tough mouse to beat.  

SteelSeries Sensei 310 Left

The SteelSeries Sensei 310 is a mouse built for gamers, meaning it’s crammed full of useful tech that designers and general users alike can benefit from. A whopping 12,000 DPI capability makes this super-sensitive (if you have it set to that high level). An ARM 32-bit processor – once a dream even for smartphones – helps compute all this data so you end up with the smoothest end result, which is what it’s all about really, isn’t it?

Evoluent VerticalMouse 4

The Evoluent VerticalMouse 4 has gone through many generations since it first appeared in 2002, and it's still going strong. The ergonomic design keeps your wrist from twisting thereby creating maximum comfort and promising long-term wrist health. The optical sensor and pointer are adjustable and buttons are available for fingers and thumbs (there are six in total). This mouse isn't cheap, but as a designer it's worth shelling out a bit more if it means keeping your wrist and hands happy.

Read more:

Switch from Mac to Windows: A 3D artist's guideThe best free fonts for designersThe best computer for graphic design

A look at the making of Google Pixel 4

Original Source: http://feedproxy.google.com/~r/abduzeedo/~3/yHCjmj0Enjw/look-making-google-pixel-4

A look at the making of Google Pixel 4
A look at the making of Google Pixel 4

AoiroStudio06.22.20

Arthur Kenzo is an industrial designer working in the Google Industrial Design Team. He shared a look of the making of the Google Pixel 4. I do own the Pixel 4 and it’s quite fascinating to see some of the behind-the-scenes of what went through the process and designing Google’s flagship phone. There is a line from Arthur’s story that I really like and as I quote: ‘Pixel 4 was designed to be soft in the hand and approachable, human.’ I do agree that when holding the Pixel 4 feels just right in your hand, the back glass is not retaining any fingertip smudges which makes the phone really defined in terms of everyday experience. Whatever you like its design or not, I think it’s always rewarding to get a glimpse of its process.

Links

http://www.arthurkenzo.com/
https://www.behance.net/arthurkenzo

Pixel 4 was designed to be soft in the hand and approachable, human. The form has been carefully sculpted out of aluminum and curved Gorilla Glass 5. Pixel 4 design is confidently different, approachable and simple. The sophisticated yet fresh approach to materials, colors and finishes is uniquely Google.

Credits

Designed by Google Industrial Design Team
Image courtesy by Google


Why Are All Sites Optimizing For Smartphones?

Original Source: http://feedproxy.google.com/~r/Designrfix/~3/1MdfNVEnVI4/why-are-all-sites-optimizing-for-smartphones

Sites were developed for desktop devices at first but as the worldwide smartphone usage rate increased so did the site developers look for other ways to fit the desktop sensation into the much smaller screen. Mobile optimized sites offer a better experience via mobile devices than those that are not. There are millions of optimized […]

The post Why Are All Sites Optimizing For Smartphones? appeared first on designrfix.com.

Fun Animated Brand Film for Supernova Design Studio

Original Source: http://feedproxy.google.com/~r/abduzeedo/~3/xVdA24Sz4YM/fun-animated-brand-film-supernova-design-studio

Fun Animated Brand Film for Supernova Design Studio
Fun Animated Brand Film for Supernova Design Studio

abduzeedo06.18.20

Supernova is a Boutique Design Studio that helps innovative brands and businesses tell their unique stories in playful and creative ways. Founded by sisters Asavari and Shaivalini Kumar, Supernova employs a multidisciplinary approach to branding that draws upon their collective expertise in communication design and animation direction (…and all things cat.). They also have a shiny new brand design with a colorful video to showcase their new identity. 

Branding and Motion Design

Creating magic through collaboration. 

Supernova we believe that building a memorable brand requires cultivating a meaningful connection with its audience. Through intelligent strategy, beautiful design and memorable storytelling, we help wonderful products and services cut through the noise so they can change the world.

Goodbye stuffy, formal meetings and flowery pitches! At Supernova we want to skip the small talk and really get to know your hopes and dreams. Think of us as an extension of your team. We cultivate close relationships to collectively define a scope of work and collaboratively solve problems to create bespoke design solutions tailored to your business goals.


Mirage JS Deep Dive: Using Mirage JS And Cypress For UI Testing (Part 4)

Original Source: https://www.smashingmagazine.com/2020/06/mirage-javascript-cypress-ui-testing/

Mirage JS Deep Dive: Using Mirage JS And Cypress For UI Testing (Part 4)

Mirage JS Deep Dive: Using Mirage JS And Cypress For UI Testing (Part 4)

Kelvin Omereshone

2020-06-17T10:30:00+00:00
2020-06-17T21:48:15+00:00

One of my favorite quotes about software testing is from the Flutter documentation. It says:

“How can you ensure that your app continues to work as you add more features or change existing functionality? By writing tests.”

On that note, this last part of the Mirage JS Deep Dive series will focus on using Mirage to test your JavaScript front-end application.

Note: This article assumes a Cypress environment. Cypress is a testing framework for UI testing. You can, however, transfer the knowledge here to whatever UI testing environment or framework you use.

Read Previous Parts Of The Series:

Part 1: Understanding Mirage JS Models And Associations
Part 2: Understanding Factories, Fixtures And Serializers
Part 3: Understanding Timing, Response And Passthrough

UI Tests Primer

UI or User Interface test is a form of acceptance testing done to verify the user flows of your front-end application. The emphasis of these kinds of software tests is on the end-user that is the actual person who will be interacting with your web application on a variety of devices ranging from desktops, laptops to mobile devices. These users would be interfacing or interacting with your application using input devices such as a keyboard, mouse, or touch screens. UI tests, therefore, are written to mimic the user interaction with your application as close as possible.

Let’s take an e-commerce website for example. A typical UI test scenario would be:

The user can view the list of products when visiting the homepage.

Other UI test scenarios might be:

The user can see the name of a product on the product’s detail page.
The user can click on the “add to cart” button.
The user can checkout.

You get the idea, right?

In making UI Tests, you will mostly be relying on your back-end states, i.e. did it return the products or an error? The role Mirage plays in this is to make those server states available for you to tweak as you need. So instead of making an actual request to your production server in your UI tests, you make the request to Mirage mock server.

For the remaining part of this article, we will be performing UI tests on a fictitious e-commerce web application UI. So let’s get started.

Our First UI Test

As earlier stated, this article assumes a Cypress environment. Cypress makes testing UI on the web fast and easy. You could simulate clicks and navigation and you can programmatically visit routes in your application. See the docs for more on Cypress.

So, assuming Cypress and Mirage are available to us, let’s start off by defining a proxy function for your API request. We can do so in the support/index.js file of our Cypress setup. Just paste the following code in:

// cypress/support/index.js
Cypress.on(“window:before:load”, (win) => {
win.handleFromCypress = function (request) {
return fetch(request.url, {
method: request.method,
headers: request.requestHeaders,
body: request.requestBody,
}).then((res) => {
let content =
res.headers.map[“content-type”] === “application/json”
? res.json()
: res.text()
return new Promise((resolve) => {
content.then((body) => resolve([res.status, res.headers, body]))
})
})
}
})

Then, in your app bootstrapping file (main.js for Vue, index.js for React), we’ll use Mirage to proxy your app’s API requests to the handleFromCypress function only when Cypress is running. Here is the code for that:

import { Server, Response } from “miragejs”

if (window.Cypress) {
new Server({
environment: “test”,
routes() {
let methods = [“get”, “put”, “patch”, “post”, “delete”]
methods.forEach((method) => {
this[method](“/*”, async (schema, request) => {
let [status, headers, body] = await window.handleFromCypress(request)
return new Response(status, headers, body)
})
})
},
})
}

With that setup, anytime Cypress is running, your app knows to use Mirage as the mock server for all API requests.

Let’s continue writing some UI tests. We’ll begin by testing our homepage to see if it has 5 products displayed. To do this in Cypress, we need to create a homepage.test.js file in the tests folder in the root of your project directory. Next, we’ll tell Cypress to do the following:

Visit the homepage i.e / route
Then assert if it has li elements with the class of product and also checks if they are 5 in numbers.

Here is the code:

// homepage.test.js
it(‘shows the products’, () => {
cy.visit(‘/’);

cy.get(‘li.product’).should(‘have.length’, 5);
});

You might have guessed that this test would fail because we don’t have a production server returning 5 products to our front-end application. So what do we do? We mock out the server in Mirage! If we bring in Mirage, it can intercept all network calls in our tests. Let’s do this below and start the Mirage server before each test in the beforeEach function and also shut it down in the afterEach function. The beforeEach and afterEach functions are both provided by Cypress and they were made available so you could run code before and after each test run in your test suite — hence the name. So let’s see the code for this:

// homepage.test.js
import { Server } from “miragejs”

let server

beforeEach(() => {
server = new Server()
})

afterEach(() => {
server.shutdown()
})

it(“shows the products”, function () {
cy.visit(“/”)

cy.get(“li.product”).should(“have.length”, 5)
})

Okay, we are getting somewhere; we have imported the Server from Mirage and we are starting it and shutting it down in beforeEach and afterEach functions respectively. Let’s go about mocking our product resource.

// homepage.test.js
import { Server, Model } from ‘miragejs’;

let server;

beforeEach(() => {
server = new Server({
models: {
product: Model,
},

routes() {
this.namespace = ‘api’;

this.get(‘products’, ({ products }, request) => {
return products.all();
});
},
});
});

afterEach(() => {
server.shutdown();
});

it(‘shows the products’, function() {
cy.visit(‘/’);

cy.get(‘li.product’).should(‘have.length’, 5);
});

Note: You can always take a peek at the previous parts of this series if you don’t understand the Mirage bits of the above code snippet.

Part 1: Understanding Mirage JS Models And Associations
Part 2: Understanding Factories, Fixtures And Serializers
Part 3: Understanding Timing, Response And Passthrough

Okay, we have started fleshing out our Server instance by creating the product model and also by creating the route handler for the /api/products route. However, if we run our tests, it will fail because we don’t have any products in the Mirage database yet.

Let’s populate the Mirage database with some products. In order to do this, we could have used the create() method on our server instance, but creating 5 products by hand seems pretty tedious. There should be a better way.

Ah yes, there is. Let’s utilize factories (as explained in the second part of this series). We’ll need to create our product factory like so:

// homepage.test.js
import { Server, Model, Factory } from ‘miragejs’;

let server;

beforeEach(() => {
server = new Server({
models: {
product: Model,
},
factories: {
product: Factory.extend({
name(i) {
return `Product ${i}`
}
})
},

routes() {
this.namespace = ‘api’;

this.get(‘products’, ({ products }, request) => {
return products.all();
});
},
});
});

afterEach(() => {
server.shutdown();
});

it(‘shows the products’, function() {
cy.visit(‘/’);

cy.get(‘li.product’).should(‘have.length’, 5);
});

Then, finally, we’ll use createList() to quickly create the 5 products that our test needs to pass.

Let’s do this:

// homepage.test.js
import { Server, Model, Factory } from ‘miragejs’;

let server;

beforeEach(() => {
server = new Server({
models: {
product: Model,
},
factories: {
product: Factory.extend({
name(i) {
return `Product ${i}`
}
})
},

routes() {
this.namespace = ‘api’;

this.get(‘products’, ({ products }, request) => {
return products.all();
});
},
});
});

afterEach(() => {
server.shutdown();
});

it(‘shows the products’, function() {
server.createList(“product”, 5)
cy.visit(‘/’);

cy.get(‘li.product’).should(‘have.length’, 5);
});

So when we run our test, it passes!

Note: After each test, Mirage’s server is shutdown and reset, so none of this state will leak across tests.

Avoiding Multiple Mirage Server

If you have been following along this series, you’d notice when we were using Mirage in development to intercept our network requests; we had a server.js file in the root of our app where we set up Mirage. In the spirit of DRY (Don’t Repeat Yourself), I think it would be good to utilize that server instance instead of having two separate instances of Mirage for both development and testing. To do this (in case you don’t have a server.js file already), just create one in your project src directory.

Note: Your structure will differ if you are using a JavaScript framework but the general idea is to setup up the server.js file in the src root of your project.

So with this new structure, we’ll export a function in server.js that is responsible for creating our Mirage server instance. Let’s do that:

// src/server.js

export function makeServer() { /* Mirage code goes here */}

Let’s complete the implementation of the makeServer function by removing the Mirage JS server we created in homepage.test.js and adding it to the makeServer function body:

import { Server, Model, Factory } from ‘miragejs’;

export function makeServer() {
let server = new Server({
models: {
product: Model,
},
factories: {
product: Factory.extend({
name(i) {
return `Product ${i}`;
},
}),
},
routes() {
this.namespace = ‘api’;

this.get(‘/products’, ({ products }) => {
return products.all();
});
},
seeds(server) {
server.createList(‘product’, 5);
},
});
return server;
}

Now all you have to do is import makeServer in your test. Using a single Mirage Server instance is cleaner; this way you don’t have to maintain two server instances for both development and test environments.

After importing the makeServer function, our test should now look like this:

import { makeServer } from ‘/path/to/server’;

let server;

beforeEach(() => {
server = makeServer();
});

afterEach(() => {
server.shutdown();
});

it(‘shows the products’, function() {
server.createList(‘product’, 5);

cy.visit(‘/’);

cy.get(‘li.product’).should(‘have.length’, 5);
});

So we now have a central Mirage server that serves us in both development and testing. You can also use the makeServer function to start Mirage in development (see first part of this series).

Your Mirage code should not find it’s way into production. Therefore, depending on your build setup, you would need to only start Mirage during development mode.

Note: Read my article on how to set up API Mocking with Mirage and Vue.js to see how I did that in Vue so you could replicate in whatever front-end framework you use.

Testing Environment

Mirage has two environments: development (default) and test. In development mode, the Mirage server will have a default response time of 400ms(which you can customize. See the third article of this series for that), logs all server responses to the console, and loads the development seeds.

However, in the test environment, we have:

0 delays to keep our tests fast
Mirage suppresses all logs so as not to pollute your CI logs
Mirage will also ignore the seeds() function so that your seed data can be used solely for development but won’t leak into your tests. This helps keep your tests deterministic.

Let’s update our makeServer so we can have the benefit of the test environment. To do that, we’ll make it accept an object with the environment option(we will default it to development and override it in our test). Our server.js should now look like this:

// src/server.js
import { Server, Model, Factory } from ‘miragejs’;

export function makeServer({ environment = ‘development’ } = {}) {
let server = new Server({
environment,

models: {
product: Model,
},
factories: {
product: Factory.extend({
name(i) {
return `Product ${i}`;
},
}),
},

routes() {
this.namespace = ‘api’;

this.get(‘/products’, ({ products }) => {
return products.all();
});
},
seeds(server) {
server.createList(‘product’, 5);
},
});
return server;
}

Also note that we are passing the environment option to the Mirage server instance using the ES6 property shorthand. Now with this in place, let’s update our test to override the environment value to test. Our test now looks like this:

import { makeServer } from ‘/path/to/server’;

let server;

beforeEach(() => {
server = makeServer({ environment: ‘test’ });
});

afterEach(() => {
server.shutdown();
});

it(‘shows the products’, function() {
server.createList(‘product’, 5);

cy.visit(‘/’);

cy.get(‘li.product’).should(‘have.length’, 5);
});

AAA Testing

Mirage encourages a standard for testing called the triple-A or AAA testing approach. This stands for Arrange, Act and Assert. You could see this structure in our above test already:

it(“shows all the products”, function () {
// ARRANGE
server.createList(“product”, 5)

// ACT
cy.visit(“/”)

// ASSERT
cy.get(“li.product”).should(“have.length”, 5)
})

You might need to break this pattern but 9 times out of 10 it should work just fine for your tests.

Let’s Test Errors

So far, we’ve tested our homepage to see if it has 5 products, however, what if the server is down or something went wrong with fetching the products? We don’t need to wait for the server to be down to work on how our UI would look like in such a case. We can simply simulate that scenario with Mirage.

Let’s return a 500 (Server error) when the user is on the homepage. As we have seen in a previous article, to customize Mirage responses we make use of the Response class. Let’s import it and write our test.

homepage.test.js
import { Response } from “miragejs”

it(‘shows an error when fetching products fails’, function() {
server.get(‘/products’, () => {
return new Response(
500,
{},
{ error: “Can’t fetch products at this time” }
);
});

cy.visit(‘/’);

cy.get(‘div.error’).should(‘contain’, “Can’t fetch products at this time”);
});

What a world of flexibility! We just override the response Mirage would return in order to test how our UI would display if it failed fetching products. Our overall homepage.test.js file would now look like this:

// homepage.test.js
import { Response } from ‘miragejs’;
import { makeServer } from ‘path/to/server’;

let server;

beforeEach(() => {
server = makeServer({ environment: ‘test’ });
});

afterEach(() => {
server.shutdown();
});

it(‘shows the products’, function() {
server.createList(‘product’, 5);

cy.visit(‘/’);

cy.get(‘li.product’).should(‘have.length’, 5);
});

it(‘shows an error when fetching products fails’, function() {
server.get(‘/products’, () => {
return new Response(
500,
{},
{ error: “Can’t fetch products at this time” }
);
});

cy.visit(‘/’);

cy.get(‘div.error’).should(‘contain’, “Can’t fetch products at this time”);
});

Note the modification we did to the /api/products handler only lives in our test. That means it works as we previously define when you are in development mode.

So when we run our tests, both should pass.

Note: I believe its worthy of noting that the elements we are querying for in Cypress should exist in your front-end UI. Cypress doesn’t create HTML elements for you.

Testing The Product Detail Page

Finally, let’s test the UI of the product detail page. So this is what we are testing for:

User can see the product name on the product detail page

Let’s get to it. First, we create a new test to test this user flow.

Here is the test:

it(“shows the product’s name on the detail route”, function() {
let product = this.server.create(‘product’, {
name: ‘Korg Piano’,
});

cy.visit(`/${product.id}`);

cy.get(‘h1’).should(‘contain’, ‘Korg Piano’);
});

Your homepage.test.js should finally look like this.

// homepage.test.js
import { Response } from ‘miragejs’;
import { makeServer } from ‘path/to/server;

let server;

beforeEach(() => {
server = makeServer({ environment: ‘test’ });
});

afterEach(() => {
server.shutdown();
});

it(‘shows the products’, function() {
console.log(server);
server.createList(‘product’, 5);

cy.visit(‘/’);

cy.get(‘li.product’).should(‘have.length’, 5);
});

it(‘shows an error when fetching products fails’, function() {
server.get(‘/products’, () => {
return new Response(
500,
{},
{ error: “Can’t fetch products at this time” }
);
});

cy.visit(‘/’);

cy.get(‘div.error’).should(‘contain’, “Can’t fetch products at this time”);
});

it(“shows the product’s name on the detail route”, function() {
let product = server.create(‘product’, {
name: ‘Korg Piano’,
});

cy.visit(`/${product.id}`);

cy.get(‘h1’).should(‘contain’, ‘Korg Piano’);
});

When you run your tests, all three should pass.

Wrapping Up

It’s been fun showing you the inners of Mirage JS in this series. I hope you have been better equipped to start having a better front-end development experience by using Mirage to mock out your back-end server. I also hope you’ll use the knowledge from this article to write more acceptance/UI/end-to-end tests for your front-end applications.

Part 1: Understanding Mirage JS Models And Associations
Part 2: Understanding Factories, Fixtures And Serializers
Part 3: Understanding Timing, Response And Passthrough
Part 4: Using Mirage JS And Cypress For UI Testing

Smashing Editorial
(ra, il)

Collective #609

Original Source: http://feedproxy.google.com/~r/tympanus/~3/5obsmHkgUpQ/

Inspirational Website of the Week: Studio Almond

Studio Almond has an equisitely fine design with some lovely animations. Our pick this week.

Get inspired

Our Sponsor
Create WordPress sites with easy using Divi

You’ve never built a WordPress website like this before. Divi is more than just a WordPress theme, it’s a completely new website building platform that replaces the standard WordPress post editor with a vastly superior visual editor.

Check it out

Color Copy Paste

Cross-platform color copy paste from phone’s camera to web, Figma and Sketch plugin.

Check it out

Hybrid positioning with CSS variables and max()

Lea Verou shares a solution for a tricky layout problem.

Check it out

Shape Divider App

Create fully responsive SVG shape dividers with customised code.

Check it out

The Mad Magazine Fold-In Effect in CSS

Thomas Park made a CSS-based web version of the wonderful Mad Magazine’s Fold-Ins by comic artist Al Jaffee.

Read it

Perceptually Smooth Multi-Color Linear Gradients

An interactive article by Matt DesLauriers on how to create perceptually smooth CIELAB spline gradients.

Check it out

Grid for layout, Flexbox for components

In this article Ahmad Shadeed explores the question about when to use Flexbox and when it’s better to use Grid.

Read it

Optimizing keyboard navigation using tabindex and ARIA

Sara Soueidan’s case study on how reducing the number of tab stops for consecutive identical links might improve the experience for keyboard users.

Read it

CSS tip

A great tip by Hakim El Hattab on using inset box-shadows.

Check it out

The complete guide to CSS media queries

A packed guide on media queries and how to use them.

Read it

Frontend Mentor Challenges

Learn how to create 14 different websites from scratch using HTML/CSS and JavaScript in this live series from the Frontend Mentor website.

Watch it

HTML5 Boilerplate 8.0.0 Released

Read all about the 10th anniversary release of the epic HTML5 Boilerplate.

Read it

Cool Little CSS Grid Tricks for Your Blog

Join Ana Tudor on an insightful journey through CSS madness and how to solve an interesting layout problem.

Read it

CSS Grid: Newspaper Layout

A fantastic newspaper layout made by Olivia Ng.

Check it out

Web Platform Contribution Guide

A beginners guide to becoming a web platform contributor.

Check it out

CSS :is() and :where() are coming to browsers

Read how the new CSS :is() and :where() pseudo-classes are now supported in some browsers. By Šime Vidas.

Check it out

Revisiting Array.reduce()

Chris Fernandi revisits the Array.reduce() examples from one of his previous articles, and shows how he would approach those same tasks today.

Read it

No Design Development

A collection of tools for developers who have little to no artistic talent.

Check it out

The Surprising Things That CSS Can Animate

Will Boyd explores some not-so-usual CSS properties for animations.

Read it

JazzKeys

JazzKeys lets you sculpt your messages using music.

Check it out

How Wikipedia Lost 3 Billion Organic Search Visits To Google in 2019

A very interesting article on Wikipedia’s traffic loss due to “zero-click results”.

Read it

Supporting Dark Mode in Your Website

Another good guide on implementing light and dark modes on websites.

Read it

The Need for Speed, 23 Years Later

An short analysis on how, in spite of an increase in Internet speed, webpage speeds have not improved over time.

Read it

Drag to confirm

A very nice button interaction idea by Aaron Ilker.

Check it out

Grid.js

In case you didn’t know about it: Grid.js is a lightweight, advanced table plugin that works everywhere.

Check it out

Blobs

Another gem you migh have missed: Customizable blobs as SVG and Flutter Widget.

Check it out

From Our Blog
How to Create a Motion Hover Effect for a Background Image Grid

A short tutorial on how to achieve a motion hover effect on a background image grid.

Check it out

The post Collective #609 appeared first on Codrops.

Smashing Podcast Episode 18 With Mina Markham: How Can I Learn React?

Original Source: https://www.smashingmagazine.com/2020/06/smashing-podcast-episode-18/

Smashing Podcast Episode 18 With Mina Markham: How Can I Learn React?

Smashing Podcast Episode 18 With Mina Markham: How Can I Learn React?

Drew McLellan

2020-06-16T05:00:00+00:00
2020-06-16T15:33:25+00:00

Photo of Mina MarkhamIn this episode of the Smashing Podcast, we’re talking about learning React. What’s React like to work with, and how can experienced developers get started? I spoke to Mina Markham to find out.

Show Notes

Mina Markham on Twitter
Mina’s personal website

Weekly Update

From Static Sites To End User JAMstack Apps With FaunaDB by Bryan Robinson
Is Your Website Stressing Out Visitors? by Suzanna Scacca
Mirage JS Deep Dive: Understanding Timing, Response And Passthrough (Part 3) by Kelvin Omereshone
Building A Facial Recognition Web Application With React by Adeneye David Abiodun
Internationalization In Vue With The Vue I18n Plugin by Timi Omoyeni

Transcript

Drew McLellan: She is a front-end architect, conference speaker and organizer, and lover of design systems. Her work on the Pantsuit patent library for Hillary Clinton’s Hillary for America presidential campaign marked a watershed for design systems within the industry and was featured on publications, such as Wired, Fast Company, and Communication Arts. Like many of us, she writes code for a living, currently as a senior engineer at Slack. So we know she’s a talented and forward thinking developer, but did you know she was once mistaken for Patrick Swayze? My smashing friends, please welcome Mina Markham. Hi Mina. How are you?

Mina Markham: I’m smashing.

Drew: Good to hear. Now, sometimes on the Smashing Podcast, we talk to people about the subject that they’re best known for. And sometimes it’s fun just to talk about something a bit tangential. Now, I could chat to you all day about pattern libraries, design systems, the amazing work you’ve done in that particular area, and I could talk to you about subjects that you’ve perhaps spoken about, events, such as the Event Apart, things like art direction. And we could obviously talk about CSS until the cows come home. But you tweeted a few days ago, and I realized that we’re actually both in the same boat in that we’re both experienced front-end engineers and we’re both recently started working with React. So before we get onto React itself, where were you coming to up to this point? Had you been working with other libraries and frameworks for JavaScript development?

Mina: No, actually I’ve been doing mostly vanilla JavaScript for a while. And before that, of course I got into JavaScript. Let me rephrase that. I started working with Java script using jQuery because it made the most sense to me. It was something that was very easily for me to parse to figure out what was happening. And then from there I backtracked to doing just vanilla, plain JavaScript, ESX, and I hadn’t really gotten too much into the framework wars. I had no, like I had no favorite. I had no dog in the fight. I was like, “For you, React, whatever. I don’t really care.” But times change.

Drew: And in this sort of way of working with vanilla JavaScript, because I’ve done a lot of that myself as well. I’ve worked with various frameworks. I’ve done a lot with jQuery back in the day. I worked with YUI, Yahoo User Interface Library. Had you felt many of the pain points that something like React’s architecture tries to address?

Mina: I don’t think I ever had. I spent most of my career making websites versus web apps and things like that. So everything I did was pretty static up to a certain extent. So I never really had to deal with state management, things like that. So the pain points that React attempts to solve I had never really applied to the kind of work that I did.

Drew: Generally speaking, what’s the sort of nature of the projects that you’ve with React so far?

Mina: It was actually only been the one project, which I’m currently working on and I can’t give away too many details because public company and all that good stuff.

Drew: Of course.

Mina: But essentially what I’m trying to do is I’m trying to use React to, it’s a very interactive sort of product where I need people to be able to enter in and save data at a certain state and then manipulate it and generate something else with said data. And that’s just something that it’s not simple DOM manipulation at that point. It really is a lot of more complex, front-end manage of data and managing the state of said data. So there really was no other alternative but to use some kind of library that attempts to solve that problem. I knew I wouldn’t be able to get past with just plain JavaScript. I contemplated maybe handling somethings on the server side, but again, due to the very interactive nature of what I’m working with, it need to be in the client. And so we already use React at Slack for various other things. And so I was like, “Okay, well we just should go ahead and adopt the same thing that the rest of the parent the companies are using and go from there.”

Drew: One of the things that I’m always seems to be a pain point with people picking up React is getting to grips with the tool chain that’s needed to get things working, Webpack being an obvious elephant in the room. Have you had to do much configuration of the tool chain or like me if you had the luxury of teammates doing it for you?

Mina: Oh, I love the infrastructure team at Slack the data. The front-end infrastructure team at Slack, they handled all of that. I didn’t have to think about it. It was great. Because I tried to learn React before in the past. Usually the way I learn best is by actually working and implementing on things. And we use React to build a lot of hillaryclinton.com back in 2016. So it’s not like I’ve never worked with people who use it. It’s just my work never directly needed me to get involved. But that code base was very complex and very sophisticated, and there was so much happening that there’s such a barrier to entry to try to learn anything in there if you didn’t already know how React and Redux and all of that works, which I didn’t. So I wasn’t really effective in learning in that environment.

Mina: Luckily, here I do have people to like take away a little bit more of the complex bits of it. I don’t have to worry about the Webpack config at all. That’s been set up. That’s been tried and tested and ready to go. I am in a similar boat where we also use Redux in addition to React, which I didn’t realize were two different things. I didn’t know which part handled which. Dropping into a code base like that, it was a little disorienting because I didn’t realize that they were all the same thing. I had people who were seasoned React developers telling me, “Oh, we also are using Redux, which makes it a little bit harder for you to really learn what React all can do if you’re starting from scratch.” And I never quite knew what they meant by that because I didn’t know what they were talking about.

Mina: To answer your original question, I am still having a little bit more of a little bit barrier to entry, because it’s not just learning React. I’m having to learn React and also how to use the Redux store. So those two things at the same time can be a little much.

Drew: Yeah, I’ve found exactly the same thing coming into an existing code base as my first React project that uses Redux. And I think as is the nature of any of these sort of technologies when they’re young, they iterate really quickly, and what’s best practice at one point, 6 months later has moved on and there’s a different way of doing things. And when you have a code base that spans many years, you can sometimes have different styles of implementing things in there. It doesn’t always keep sync. And of course, if you’re following a tutorial or whatever to learn, you’re reading books, you’re using resources, they will be in the most modern version of how to do things. And that doesn’t necessarily nit to what you see when you look at an existing, mature product. Is that something you’d experienced at all, or have you managed to keep your code base really up to date?

Mina: I think that is something that I definitely have been experiencing. When I tried to learn how to do React on my own, I looked at various tutorials and things like that. And I noticed, or at least people have told me who have worked who have been working with me that some of the things that we do or kind of anti-pattern or not quite how things work now, because this code base is slightly, well mature us relative, but it’s a few years old. And so there are some ways that I guess are easier to do things than the way we’re doing them currently because this was written years ago. So it’s a little bit of a treadmill trying to keep up with current times and make sure I want to do things the best way, but also I don’t want to break an established code base because I want to play around with stuff.

Drew: Obviously, one of the things with React that people like you and I are coming to it, it can feel a bit jarring as this whole thing with JSX. Are you using JSX in your project?

Mina: We are. I am using JSX.

Drew: Have you made peace with that?

Mina: I fell like a little small piece of me dies every time I open one of those files. It still feels sacrilege to put my HTML in the JavaScript file. I know that’s kind of revolutionary and the whole point, but it just feels off to me that I’m writing my markup in a JavaScript file. I’ve made peace with it, but every time I do it, I’m just like, “…” Separation concerns, it is a thing. I’d like it back, please.

Drew: It’s a valid point, isn’t it? My background when I was starting to work more seriously with JavaScript, and this was probably when I was back at Yahoo, things were very much on the model of server rendered HTML pages and then taking a progressive enhancement approach, layering JavaScript on top to enhance the interface. And if the state of something in the interface needed to change, your code had to know about all the parts of the interface that it needed to update, which obviously leads you to a tightly coupled approach with these big monolithic views where the code you write needs to know about all the other code around it. And I guess that doesn’t really lend itself to a componentized approach which you would take when working with a pattern library or a design system, which is more to your area of particular expertise. I guess, React lends itself more to that approach, does it?

Mina: I think it does, especially with the being able to couple the very specific CSS to one JSX or one React component. And so that way it makes it much easier to separate or only take what you need for the library and leave the rest, whereas a pattern library or design system that attempts to do something more monolithic with just one big style CSS file or something like that, it does make it a lot difficult. You kind of have to take it all or nothing. So I do appreciate that React allows us to do more individualized, more componentized way of development, even if I still wish there was a way for me to do truly separate my presentation layer and my content layer from my interactivity layer. But maybe that’s just me being a little bit old school in that sense.

Drew: I definitely feel the pain there. The idea is that, come and correct me if I’m wrong, my understanding is that rather than separating the technologies, the CSS, and the JavaScript, and the HTML, it’s separating the functionality. So everything that is one component all exist together-

Mina: Yeah.

Drew: … which I guess is useful if that component then is no longer needed. You can just delete it, and it’s gone, and it doesn’t leave a footprint around your app. That’s not always the case with CSS though. How are you working with CSS with React? Have You looked at things like styled-components or anything like that?

Mina: No, we haven’t. I’ve heard of styled-components, but I’ve never quite really investigated them very fully to be perfectly honest. So the way that we’re working with CSS with React is we write Less, and we just have a Less file attached to each individual component that gets imported into that component. And then it gets bonded up via Webpack and served to the client.

Drew: Are you using a system like BEM or something to turn namespace?

Mina: Yeah. We’re using BEM for namespacing, although the adherence to it is kind of varied depending on who’s writing what. But we try to use a BEM namespacing pattern to make it a little bit clearer what the purpose of each individual class and component is.

Drew: And does that seem to be working successfully for you?

Mina: I think so. Occasionally it kind of has the same old problem of I sometimes don’t know how to name something. After a while daily things has always and will always be a difficult thing for master. So that’s the only issue I have with is I occasionally I have no idea what I should call a particular component.

Drew: Definitely. That’s a constant battle, isn’t it, how to out the name things?

Mina: Yeah.

Drew: I always end up when working on a new feature or something like that, you give a component and all the classes and everything the name that the feature has got at the moment. And then by the time you come to launch, it’s been renamed something else. So you have references to the old name in the code and the interface has the new name. And …

Mina: I try to always name things based on the function or the purpose of it versus things that are a little bit more ephemeral, because it’s less likely that the actual purpose of this component will change. I forgot to mention, but in addition to using BEM, I guess we use BEMITs if you’re familiar with that. It’s basically the ITCSS plus BEM, both of which were created by Harry Roberts. So I use Hungarian notation to denote whether or not something is a component, versus a layout object, versus like a larger pattern comprised of multiple components. And then from there we use the BEM convention to signify like the block element and all that.

Drew: And have you had to do much refactoring and deleting of components and things in your code base and had to deal with the issue of CSS getting left behind?

Mina: Yeah. So the non-React part of my job, of maintaining slack.com is that’s all just a bunch of Less files that are being compiled for CSS. And I guarantee you, there’s a lot of zombie code in there, because we definitely iterate above things a lot in the time I’ve been there. And we don’t always have time to go back and do the cleanup versus when we redesign a page or something. So it’s overdue for an audit, I’ll say that.

Drew: This is something that we’ve just been looking at in our React project, looking at how we approach CSS. At the moment, we have a few big, global CSS files for the whole of the app, and we do get this situation where our bundle size is just growing, and growing, and growing and never gets any smaller, even though things do get removed. So we’ve been looking at things like styled-components, Tailwind as well is another option that we’re really seriously considering. Have you looked at tailwind much?

Mina: I haven’t looked at it a lot. I’ve been curious about it, but again, I’ve never really had time to dig in to actually see if it’s something that I want to try to bring into our code base.

Drew: I was actually quite surprised, because like you, I’m a bit old school with how to do these things. I like nice separation of concerns. And I like to write my CSS in CSS, and of course the approach with Tailwind is you have all these class names, which feel a bit like inline styles that you’re applying. And if it feels dirty.

Mina: Yeah.

Drew: And I volunteered within the team, we each which took a technology to investigate if they’d be a good fit for our problems, and I volunteered to look at Tailwind because I was absolutely certain I was going to hate it.

Mina: No, no.

Drew: But it turns out I actually think it solves a lot of problems. I was quite impressed.

Mina: Yeah. I’ve sort of come around to a similar way of thinking, because I in the past would much prefer to have one class comprise all of the styles I needed for a particular component and not do a class per property, as I believe Tailwind does or languages like it do. For the similar reasons, it felt very much like, “Well, I’m just running inline CSS at this point. Why would I do this?” But as I’ve been developing more and more, inside of our Slack design system, I created a bunch of what I call utility classes that do things like add a bit of margin with a pattern. I’ve noticed that more and more, I’m using those classes in addition to the component classes. So I’m like, “Okay, well maybe I should revisit this whole to doing a CSS as a one declaration at a time.” I don’t know if I’d go that far, but it’s definitely worth considering.

Drew: Computing seems to flip flop in terms of trends between thin clients and fat clients solutions. We started with mainframes with terminals, and then the PC era with windows and office and all these sort of big applications. And they were all getting really slow, and than the web came along, and that was just a browser, and all the work was being done on the server. And it was all fast and snappy again. And now we’ve gone back to putting all that work back in the browser with everything being done with JavaScript, things like React and the JAMstack approach where we’re back to a sort of fat client. I sometimes worry that we’re asking too much of the browser. Is this a mistake? Are we asking too much of the browser trying to do all this stuff in React?

Mina: I want to say yes with the caveat of, again, my experience is very much contained to mostly static websites. I don’t do a lot of product development. So maybe in that realm, this makes more sense. But from my perspective, I feel like we’re a lot of the times using a hatchet when we just need a butter knife. I don’t know why we need put all this in the browser, put so much work and so much pressure on the client. I feel like we could do this much simpler. One of the things that always made me a little hesitant to use React, or I say hesitant, but what I mean when it made me viscerally angry and I actively opposed, was when I would go to a website and literally nothing would render because there was one error or something, Like, “Really? The entire page is broken because one function broke down?”

Mina: It just kind of annoyed me that a lot of times it was an all or nothing approach. One of the talks that I gave at AEA in the past and other places in the past was talking about how to include progressive enhancement and not just your development, but also of art direction and design of sites. And I would point out specifically examples of websites that didn’t do progressive enhancement or any kind of graceful degradation. It was like either you have the JavaScript running in the browser or you get absolutely nothing. And it would be like just a simple site that represent information about the history of web design, which was one of the sites actually talked about, the history of web design from like 1990 until now. It was a beautiful website with lots of timelines, animation of things. But it also could have been rendered statically with just a list. There were steps in between showing nothing and showing that beautifully enhanced experience that I think got lost because of the way we’ve been approaching modern web development now.

Drew: So would you say there are absolutely some categories of projects that suit a solution like React and some where it really shouldn’t be used and you should be using more traditional methods?

Mina: I think that if your site particularly is mostly static, it was just serving up information, I guess I don’t understand why you need a project like React to render something that doesn’t have a lot of interaction beyond just DOM manipulation. I guess I don’t see what benefit you get from that. Again, I may not be working on the appropriate projects. I may not just have seen or found that use case, but I’m having a hard time seeing if it’s just mostly static site, presenting content, not a lot interaction, not a lot of interaction beyond manipulated DOM and doing animations. I don’t see how having a React library helps you accomplish that goal.

Drew: It’s interesting because I’m not bad talking it because I haven’t actually used it, but I see a lot of Gatsby projects and Gatsby being a static site generator that uses a React front-end in it. And I see all the examples of the themes and things they have available are all content based sites, or blogs, and a recipe site, and a portfolio, and these sort of things. And there’s something I think actually that this isn’t necessarily the right fit for something like React. Why isn’t this being statically rendered and then progressively enhance?

Mina: Yeah.

Drew: It’s not software.

Mina: Yeah. I haven’t actually used Gatsby either. I’ve heard plenty of great things about it, but that’s probably one of the examples I would think of where I’m like, “Okay, I guess I’m just not seeing why that tool is necessary to do that particular job.” Again, I don’t know. Maybe it’s just because more people are comfortable writing in React when they are writing new something else, and it’s just providing a tool that meets people where they are. I’ve heard great things about static site generators that use React for people who have used them and love them, but it’s not a use case that I would have immediately been like, “Oh, that makes sense.”

Drew: It seems like there’s always been this battle between what we would call a website and what you might call a web app. And the chasm between the two seems to be getting wider, and wider, and wider, whereas a progressive enhancement approach tries to bridge the gap by taking something static and adding JavaScript and adding interactivity. It seems that things like React are ideally suited for software that you’re running in the browser. Would you agree with that?

Mina: I would definitely agree with that because it feels like it’s was built for that type of environment; it was built for running software. It was built by Facebook for Facebook. So it was built for a product. It was built for running whatever you call a web app in the browser and not necessarily for the type of work that, as I mentioned, I’m used to doing. So I think in those scenarios, it definitely makes a lot of sense to use it if you’re building a more complex, more sophisticated piece of software that’s meant to run inside of a browser. But if you’re building a marketing site or whatever, I guess I would still struggle to see why it will be necessary there.

Drew: So are we giving people permission to still build decent, statically rendered websites?

Mina: I would love to see more of that happen. I feel like that’s kind of gotten lost and it’s sort of lost its, if it ever was cool or whatever. I feel like we’ve lost that part of web development. It’s so funny: you and I both said that we’re kind of old school, and I laugh at that because I’ve actually been doing web development for, what, six years now? How am I old school? It hasn’t been that long for me. And yet somehow I’m part of the old guard who doesn’t like new and shiny things. I don’t get it.

Drew: So in fact React has actually existed for the whole time that you’ve been a web developer.

Mina: Maybe I just have an old soul. I don’t know.

Drew: I think that’s probably the case. I’ve not looked personally at, there are service side rendered approaches you can take with React apps. Have you experienced any of those?

Mina: I haven’t experienced any them. I briefly looked into them for the project I’m currently working on, because I feel like there’s parts of the operation that would work better on a server versus in the clients. But I think because of my limited knowledge and the fact that the code base is a little more complicated than I can understand, I wasn’t quite able to figure out how to make that part work. I would love to figure it out eventually, but I spent a day digging into it. I was like, “You know what? I’m not grokking this away I need to be. So I’m just going to back up and take a different route.”

Drew: Yeah. I think we’ve all been there.

Mina: Yeah. I went down a path. I was like, “Oh, this is dark and scary. Let’s reverse. Let’s reverse.”

Drew: Step away from the code.

Mina: Yes.

Drew: So you’ve been very diplomatic and polite about React so far. I sense that there’s some tension bubbling under the surface a bit. Come on. Tell us what you really feel.

Mina: I have been polite and diplomatic, mostly because the Reacts fan base can be a little mean sometimes, and I would rather not have them come for me. So please, React is great. It’s wonderful. Use it for what you want to use it for. I kid, but even that tweet that you mentioned at the beginning of this podcast where I think what you said is that I don’t hate it. I don’t love it, but I don’t hate it. Even that statement, I got people, there was no vitriol, but it was more they where ready to leap to the defense and say, “Well, I love it because X, Y, Z.” I’m like, “I didn’t say it was bad. I just said that I’m meh about the whole thing.” But apparently being meh is not okay. I have to love it.

Mina: So that’s why I probably have been a bit more diplomatic than I would ordinarily be, just because I don’t want people to think that I’m bad mouthing it, because I’m not. It has a place in more web development. It serves a function. It does its job well. People love it. It’s just not a tool that I’ve ever had or wanted to use until now.

Drew: Yeah. Things can get very tribal, can’t they, with people feeling like they have to take one side or another, and you’re either absolutely for something or absolutely against something? And I’m not sure it serves a good purpose, and I don’t think it really moves us forward as an industry and as a community to do that.

Mina: Yeah. It’s really odd. It’s fascinating to watch from just a sociological standpoint, but it’s often just really like weird to observe. It’s like I’m not allowed to just be, like I said, neutral about certain things. I have to have a strong opinion, which is I don’t think healthy. What’s the term, “Strong opinions, loosely held?” That’s kind of the way I go about things. I feel strongly about certain things, but it’s not like you can’t change my mind. Where I feel like some people, their identity gets wrapped up into certain aspects of it ,that if you are not for whatever they’ve chosen to identify with, it’s a personal slight versus just, I don’t care about this particular topic, or tool, or whatever.

Drew: Yes. I don’t know if it’s made worse by the fact that we all are sort of tending to specialize a lot more in particular parts of the stack. And I know there are people who are React developers. They would call themselves a React developer because that’s what they work in. And they wouldn’t necessarily write any vanilla Java script or wouldn’t use Vue or whatever. React is their world. So I guess it almost feels like an attack on their entire career to say, “I don’t like React.” Well, they’re really invested in making you like React or whatever the technology may be.

Mina: I will admit to being one of those people in the past. Actually, probably it was mostly about SASS, I believe. I was very much on the team of doing SASS as a preprocessor and all other preprocessors are trash. I don’t want to talk about them. I don’t want to deal with them. And I realized that was a very narrow way to look at things. Use the appropriate tool for the job. Whatever makes you more productive, that’s the right tool. It doesn’t really matter what it is.

Drew: Are there any technologies that we work with that don’t have that sort of tribal feel? Is there anything that people are just happy to use or not use? I can’t think of anything.

Mina: Wow. No one has opinions about markup, actually.

Drew: No.

Mina: I feel like no one has opinions about like actual HTML and just markup, just like, “It’s there.” They use it. But people have strong opinions about CSS and how it’s either terrible or wonderful, and the preprocessor wars that don’t really happen all that much anymore, and then of course, all of the tribalism within the various JavaScript libraries.

Drew: So you would say your journey so far with React is still just, “It’s a tool. It does its job?”

Mina: It went from a curiosity to active and visceral dislike because of how prevalent it was and how I unnecessary I thought that that prevalence was to meh. I’m now with meh, which again does not mean I hate it. It just means …

Drew: I think that’s a good place to be. I think we’re probably all sort of stronger as technologists if we understand the value of a particular technology for its purpose. We can evaluate what is good for what circumstance and pick the right tool for the job.

Mina: Yeah. And that’s kind of where I’ve arrived at this point in my career where I don’t get really invested in any particular language, or technology, or whatever, because it’s like, “Just whatever tool is most appropriate for what you’re trying to do, then use that.” I’ve learned that there’s a place for everything; there’s a time and a place to do everything. And up until recently, there was no real time or place for me to use this React librarian, and now there is.

Drew: I think that’s a good place to be. So I’ve been learning all about React lately as you have in the day job. Is there anything else that you’ve been learning about lately?

Mina: I’ve actually learned ironically, which is I think another language that has originated at Facebook, I’ve been doing a lot of Hack development, mostly because that’s what I use at Slack, at my day job. Learning Hack paved the way for me to get more comfortable using React because they follow very similar patterns, except one is server side and one’s not. So that, along with just in general, I’ve been learning more about the back-end and how that works for various different reasons. And I’ve been stretching myself for the past couple years and getting more and more outside of my comfortable zone. Design systems, libraries, that’s very much my world, and I feel very good and comfortable in that world. But I’m stepping outside of it and doing a lot more server side logic, and API development, and data modeling, and all of that. I’ve been doing a lot on that for the past year as well.

Drew: I find that the more I understand about the whole stack about back-end stuff in front-end stuff, each one helps my knowledge of the other. I find I write better front-end code by having written back-end code and understanding-

Mina: Yeah. I think I feel the same way. Now that I have a better idea of, like we said, the whole stack of how we get from the data to the end client. I find that I’m thinking about the entire pipeline no matter what part I’m actually working in. I’m thinking about what’s the best way to structure this API so that when I get to the template, I don’t have to do so much manipulating of the data that I receive on that end of it. It’s definitely made me overall a better engineer, I feel like it

Drew: If you, dear listener, would like to hear more from Mina, you can follow her on Twitter where she’s @MinaMarkham and find her personal site at mina.codes. Thanks for joining us today, Mina. Do you have any parting words?

Mina: Have a smashing night?

Drew: Great.

Smashing Editorial
(il)

Apple 'foldable' iPhone design sparks controversy

Original Source: http://feedproxy.google.com/~r/CreativeBloq/~3/s-lc1uiAhGs/foldable-apple-iphone-design

Everyone is waiting for Apple to follow in the footsteps of its rivals and finally announce the design of a foldable phone. According to a prominent leaker-of-all-things-Apple, Jon Prosser, the tech giant could be getting closer with its recent prototypes – but, crucially, the design may not contain a flexible screen.

Apparently, Apple is working on a dual screen model, which has two separate screens put together as one, complete with a hinge. Even though Apple usually comes top of the class for its product design and innovation (the iPhone 11 is one of our best camera phones, after all), commenters have already begun to pour mirth on the idea, and the memes aren't pretty.

Source Jon Prosser is quick to defend Apple's potential design, pointing out in a separate tweet that, although the memes are funny, "it doesn't look like they just stuck two phones together. Even though they're separate panels, when the displays are extended, it looks fairly continuous and seamless". 

Reactions weren't entirely scornful, though. One, more positive, angle was the Twitter user excited about a futuristic Westworld-style tablet (above).

Apple foldable patent

Apple’s patent for a dual device system

Apple did file a patent back in March outlining plans for a "system with multiple electronic devices", which would solve the problem of the crease that is bound to occur along a flexible screen. It would also deal with the the fragility of a foldable device, a problem that has plagued the development of foldable screens at rival companies. 

Microsoft Surface Duo

Will Apple’s foldable device look like the Surface Duo?

The closest reference point to a dual screen device of this nature is Microsoft's upcoming Surface Duo (above) but is Apple's foldable phone likely to go down this route? Other Twitter users are questioning the very definition of a foldable device, asking: if it has two screens, what sets it apart from a flip phone? 

But user Mr Dan Master disagrees, pointing out that it's display size, rather than the method of folding, that makes a phone foldable.

Whether or not Apple is rewriting the rules of a foldable phone with its proposed plans, we're sure it won't look like the examples being thrown around on Prosser's twitter feed, which are hilariously clunky and crudely put together (except the Westworld tablet, of course, which would be brilliant). Plus, there's nothing to say Apple isn't currently working on a bunch of solutions for the foldable iPhone, including a flexible screen.

This foldable iPhone concept design sparked our imaginations last month, and though it is careful to avoid having to deal with the issue of the screen crease, we would hope to see something as sleek from Apple if it ever actually releases a foldable phone. 

If you're not bothered about whether your phone can bend or not, here are the best non-folding iPhone deals available now. 

Read more:

Is this Apple’s most ludicrous move yet?The best Apple Pencil alternatives in 2020Apple's bendable MacBook will blow your mind

Why copywriting is more important than you think

Original Source: http://feedproxy.google.com/~r/CreativeBloq/~3/Gy-Y3KQjAb0/why-copywriting-matters

Copywriting in branding and advertising has always been an important part of the industry, and the role of words in advertising in particular has previously been recognised at the D&AD Awards, with its Writing for Advertising category. 

This year, that category is no more, and many have been left baffled by the decision, or are at least lamenting it. Creative director Jack Davey took to Twitter to show what some famous adverts would look like without the words (below). Spoiler: it's not good. See our favourite print ads for more examples of compelling copy in advertising.

As you can see, these ads are far less impactful without their accompanying copy. In recognition of the role of words in creating powerful branding, the Brand Impact Awards has this year launched a new craft category as part of its awards scheme: copywriting. Two other new craft categories have also been launched: typography and illustration – and you have until 26 June to enter the prestigious awards. 

Brand Impact Awards 2020

Enter your best branding now

Here, judges from the Brand Impact Awards' specialist copywriting panel share how copywriting can define and invigorate a brand, and how you can best use words to shape an identity.

01. Listen and learn

copywriting in branding

Identity for performance space The Roundhouse

"Sometimes we do little more than ask intelligent, informed, pointed questions – and then listen," explains Mike Reed. "Sometimes we use workshop exercises, like pulling up famous faces: one client described how they were currently Scotty (nervous, risk-averse, caught up in technicalities) and wanted to become more Kirk (confident, direct, visionary). Your ears, and what sits between them, are your most effective tools."

02. Don't obsess over tone

"The obsession with 'tone of voice' emphasises tone over content and message, and leads to a lot of wasted investment," argues Nick Asbury. "If you think about the brands who are known for their words – let’s say Jack Daniel's, Innocent and The Economist – then the effectiveness is rooted not so much in the tone, but the content. Given a limited budget, I’d advise any client to pay a good copywriter to write as much real stuff as possible. It's more useful than any tone of voice guidelines."

"Sometimes, brands get caught up in wanting to sound different or show loads of personality through their words, when what they actually need is to be clear and straightforward, and focus on writing well," suggests Kate van der Borgh. "Tone can come afterwards, and it might be very subtle."

03. Don't patronise your audience

copywriting in branding

Vikki Ross has crafted words for Paperchase

"We seem to be going through a phase of products talking to us in the first person," laments Vikki Ross. "You know, 'Fix me, I’m broken'; 'Take me home'; 'Buy me'. Grown-up products like machines, toiletries, champagne. Not stuff for kids, but copy like this looks like it's aimed at kids. Too twee for me."

04. Make the most of microcopy

copywriting in branding

Every word counts, as this work for Upcircle shows

"Turning an Innocent carton over to find ’Stop looking at my bottom’ remains a delight," says Reed. "But it doesn’t have to be silly. The little line of explanation under a data-entry field can be just as pleasing, if it perfectly anticipates the question forming in your head. Or if it adds a fun little twist to the process. Or – joy of joys – both."

05. Stay consistent

"Tricky things, like letters to customers apologising for something going wrong, are super important bits of brand writing," insists van der Borgh. "You see it all the time: a brand is all warm and friendly in its welcome email, but stern and overly-formal when something goes wrong. It's like a mask slipping, and it doesn't help build trust."

06. Consider something different

copywriting in branding

Part of a campaign for University of Cambridge

"Most brands stick to a narrow range in the tone of voice spectrum – somewhere around friendly, professional, warm, human," says Asbury. "But what would a sarcastic or miserable brand sound like? Could a brand be inexplicably angry with you? In a world of nice smoothies, a miserable or stoical one would stand out."

07. Stay in character

"Brands that stay true to their personality for years see results," says Ross. "Take the opportunity to make things like call-to-action buttons feel yours. For instance, Virgin Atlantic says 'Take me there' instead of 'Book now'. 'Book now' may result in more clicks, but that's for a newer brand that must be more direct with its audience at first. If brands start talking formally and functionally when they don’t usually, it puts usual customers off."

Submit your best copywriting in branding to the Brand Impact Awards by 26 June.

Read more:

5 steps to building a strong brand voiceBrand typography: a complete guideComputer Arts survived by the Brand Impact Awards

Better Reducers With Immer

Original Source: https://www.smashingmagazine.com/2020/06/better-reducers-with-immer/

Better Reducers With Immer

Better Reducers With Immer

Chidi Orji

2020-06-16T12:30:00+00:00
2020-06-16T13:04:33+00:00

As a React developer, you should be already familiar with the principle that state should not be mutated directly. You might be wondering what that means (most of us had that confusion when we started out).

This tutorial will do justice to that: you will understand what immutable state is and the need for it. You’ll also learn how to use Immer to work with immutable state and the benefits of using it.
You can find the code in this article in this Github repo.

Immutability In JavaScript And Why It Matters

Immer.js is a tiny JavaScript library was written by Michel Weststrate whose stated mission is to allow you “to work with immutable state in a more convenient way.”

But before diving into Immer, let’s quickly have a refresher about immutability in JavaScript and why it matters in a React application.

The latest ECMAScript (aka JavaScript) standard defines nine built-in data types. Of these nine types, there are six that are referred to as primitive values/types. These six primitives are undefined, number, string, boolean, bigint, and symbol. A simple check with JavaScript’s typeof operator will reveal the types of these data types.

console.log(typeof 5) // number
console.log(typeof ‘name’) // string
console.log(typeof (1 < 2)) // boolean
console.log(typeof undefined) // undefined
console.log(typeof Symbol('js')) // symbol
console.log(typeof BigInt(900719925474)) // bigint

A primitive is a value that is not an object and has no methods. Most important to our present discussion is the fact that a primitive’s value cannot be changed once it is created. Thus, primitives are said to be immutable.

The remaining three types are null, object, and function. We can also check their types using the typeof operator.

console.log(typeof null) // object
console.log(typeof [0, 1]) // object
console.log(typeof {name: ‘name’}) // object
const f = () => ({})
console.log(typeof f) // function

These types are mutable. This means that their values can be changed at any time after they are created.

You might be wondering why I have the array [0, 1] up there. Well, in JavaScriptland, an array is simply a special type of object. In case you’re also wondering about null and how it is different from undefined. undefined simply means that we haven’t set a value for a variable while null is a special case for objects. If you know something should be an object but the object is not there, you simply return null.

To illustrate with a simple example, try running the code below in your browser console.

console.log(‘aeiou’.match(/[x]/gi)) // null
console.log(‘xyzabc’.match(/[x]/gi)) // [ ‘x’ ]

String.prototype.match should return an array, which is an object type. When it can’t find such an object, it returns null. Returning undefined wouldn’t make sense here either.

Enough with that. Let’s return to discussing immutability.

According to the MDN docs:

“All types except objects define immutable values (that is, values which can’t be changed).”

This statement includes functions because they are a special type of JavaScript object. See function definition here.

Let’s take a quick look at what mutable and immutable data types mean in practice. Try running the below code in your browser console.

let a = 5;
let b = a
console.log(`a: ${a}; b: ${b}`) // a: 5; b: 5
b = 7
console.log(`a: ${a}; b: ${b}`) // a: 5; b: 7

Our results show that even though b is “derived” from a, changing the value of b doesn’t affect the value of a. This arises from the fact that when the JavaScript engine executes the statement b = a, it creates a new, separate memory location, puts 5 in there, and points b at that location.

What about objects? Consider the below code.

let c = { name: ‘some name’}
let d = c;
console.log(`c: ${JSON.stringify(c)}; d: ${JSON.stringify(d)}`) // {“name”:”some name”}; d: {“name”:”some name”}
d.name = ‘new name’
console.log(`c: ${JSON.stringify(c)}; d: ${JSON.stringify(d)}`) // {“name”:”new name”}; d: {“name”:”new name”}

We can see that changing the name property via variable d also changes it in c. This arises from the fact that when the JavaScript engine executes the statement, c = { name: ‘some name’ }, the JavaScript engine creates a space in memory, puts the object inside, and points c at it. Then, when it executes the statement d = c, the JavaScript engine just points d to the same location. It doesn’t create a new memory location. Thus any changes to the items in d is implicitly an operation on the items in c. Without much effort, we can see why this is trouble in the making.

Imagine you were developing a React application and somewhere you want to show the user’s name as some name by reading from variable c. But somewhere else you had introduced a bug in your code by manipulating the object d. This would result in the user’s name appearing as new name. If c and d were primitives we wouldn’t have that problem. But primitives are too simple for the kinds of state a typical React application has to maintain.

This is about the major reasons why it is important to maintain an immutable state in your application. I encourage you to check out a few other considerations by reading this short section from the Immutable.js README: the case for immutability.

Having understood why we need immutability in a React application, let’s now take a look at how Immer tackles the problem with its produce function.

Immer’s produce Function

Immer’s core API is very small, and the main function you’ll be working with is the produce function. produce simply takes an initial state and a callback that defines how the state should be mutated. The callback itself receives a draft (identical, but still a copy) copy of the state to which it makes all the intended update. Finally, it produces a new, immutable state with all the changes applied.

The general pattern for this sort of state update is:

// produce signature
produce(state, callback) => nextState

Let’s see how this works in practice.

import produce from ‘immer’

const initState = {
pets: [‘dog’, ‘cat’],
packages: [
{ name: ‘react’, installed: true },
{ name: ‘redux’, installed: true },
],
}

// to add a new package
const newPackage = { name: ‘immer’, installed: false }

const nextState = produce(initState, draft => {
draft.packages.push(newPackage)
})

In the above code, we simply pass the starting state and a callback that specifies how we want the mutations to happen. It’s as simple as that. We don’t need to touch any other part of the state. It leaves initState untouched and structurally shares those parts of the state that we didn’t touch between the starting and the new states. One such part in our state is the pets array. The produced nextState is an immutable state tree that has the changes we’ve made as well as the parts we didn’t modify.

Armed with this simple, but useful knowledge, let’s take a look at how produce can help us simplify our React reducers.

Writing Reducers With Immer

Suppose we have the state object defined below

const initState = {
pets: [‘dog’, ‘cat’],
packages: [
{ name: ‘react’, installed: true },
{ name: ‘redux’, installed: true },
],
};

And we wanted to add a new object, and on a subsequent step, set its installed key to true

const newPackage = { name: ‘immer’, installed: false };

If we were to do this the usual way with JavaScripts object and array spread syntax, our state reducer might look like below.

const updateReducer = (state = initState, action) => {
switch (action.type) {
case ‘ADD_PACKAGE’:
return {
…state,
packages: […state.packages, action.package],
};
case ‘UPDATE_INSTALLED’:
return {
…state,
packages: state.packages.map(pack =>
pack.name === action.name
? { …pack, installed: action.installed }
: pack
),
};
default:
return state;
}
};

We can see that this is unnecessarily verbose and prone to mistakes for this relatively simple state object. We also have to touch every part of the state, which is unnecessary. Let’s see how we can simplify this with Immer.

const updateReducerWithProduce = (state = initState, action) =>
produce(state, draft => {
switch (action.type) {
case ‘ADD_PACKAGE’:
draft.packages.push(action.package);
break;
case ‘UPDATE_INSTALLED’: {
const package = draft.packages.filter(p => p.name === action.name)[0];
if (package) package.installed = action.installed;
break;
}
default:
break;
}
});

And with a few lines of code, we have greatly simplified our reducer. Also, if we fall into the default case, Immer just returns the draft state without us needing to do anything. Notice how there is less boilerplate code and the elimination of state spreading. With Immer, we only concern ourselves with the part of the state that we want to update. If we can’t find such an item, as in the `UPDATE_INSTALLED` action, we simply move on without touching anything else.

The `produce` function also lends itself to currying. Passing a callback as the first argument to `produce` is intended to be used for currying. The signature of the curried `produce` is

//curried produce signature
produce(callback) => (state) => nextState

Let’s see how we can update our earlier state with a curried produce. Our curried produce would look like this:

const curriedProduce = produce((draft, action) => {
switch (action.type) {
case ‘ADD_PACKAGE’:
draft.packages.push(action.package);
break;
case ‘SET_INSTALLED’: {
const package = draft.packages.filter(p => p.name === action.name)[0];
if (package) package.installed = action.installed;
break;
}
default:
break;
}
});

The curried produce function accepts a function as its first argument and returns a curried produce that only now requires a state from which to produce the next state. The first argument of the function is the draft state (which will be derived from the state to be passed when calling this curried produce). Then follows every number of arguments we wish to pass to the function.

All we need to do now to use this function is to pass in the state from which we want to produce the next state and the action object like so.

// add a new package to the starting state
const nextState = curriedProduce(initState, {
type: ‘ADD_PACKAGE’,
package: newPackage,
});

// update an item in the recently produced state
const nextState2 = curriedProduce(nextState, {
type: ‘SET_INSTALLED’,
name: ‘immer’,
installed: true,
});

Note that in a React application when using the useReducer hook, we don’t need to pass the state explicitly as I’ve done above because it takes care of that.

You might be wondering, would Immer be getting a hook, like everything in React these days? Well, you’re in company with good news. Immer has two hooks for working with state: the useImmer and the useImmerReducer hooks. Let’s see how they work.

Using The useImmer And useImmerReducer Hooks

The best description of the useImmer hook comes from the use-immer README itself.

useImmer(initialState) is very similar to useState. The function returns a tuple, the first value of the tuple is the current state, the second is the updater function, which accepts an immer producer function, in which the draft can be mutated freely, until the producer ends and the changes will be made immutable and become the next state.

To make use of these hooks, you have to install them separately, in addition to the main Immer libarary.

yarn add immer use-immer

In code terms, the useImmer hook looks like below

import React from “react”;
import { useImmer } from “use-immer”;

const initState = {}
const [ data, updateData ] = useImmer(initState)

And it’s as simple as that. You could say it’s React’s useState but with a bit of steroid. To use the update function is very simple. It receives the draft state and you can modify it as much as you want like below.

// make changes to data
updateData(draft => {
// modify the draft as much as you want.
})

The creator of Immer has provided a codesandbox example which you can play around with to see how it works.

useImmerReducer is similarly simple to use if you’ve used React’s useReducer hook. It has a similar signature. Let’s see what that looks like in code terms.

import React from “react”;
import { useImmerReducer } from “use-immer”;

const initState = {}
const reducer = (draft, action) => {
switch(action.type) {
default:
break;
}
}

const [data, dataDispatch] = useImmerReducer(reducer, initState);

We can see that the reducer receives a draft state which we can modify as much as we want. There’s also a codesandbox example here for you to experiment with.

And that is how simple it is to use Immer hooks. But in case you’re still wondering why you should use Immer in your project, here’s a summary of some of the most important reasons I’ve found for using Immer.

Why You Should Use Immer

If you’ve written state management logic for any length of time you’ll quickly appreciate the simplicity Immer offers. But that is not the only benefit Immer offers.

When you use Immer, you end up writing less boilerplate code as we have seen with relatively simple reducers. This also makes deep updates relatively easy.

With libraries such as Immutable.js, you have to learn a new API to reap the benefits of immutability. But with Immer you achieve the same thing with normal JavaScript Objects, Arrays, Sets, and Maps. There’s nothing new to learn.

Immer also provides structural sharing by default. This simply means that when you make changes to a state object, Immer automatically shares the unchanged parts of the state between the new state and the previous state.

With Immer, you also get automatic object freezing which means that you cannot make changes to the produced state. For instance, when I started using Immer, I tried to apply the sort method on an array of objects returned by Immer’s produce function. It threw an error telling me I can’t make any changes to the array. I had to apply the array slice method before applying sort. Once again, the produced nextState is an immutable state tree.

Immer is also strongly typed and very small at just 3KB when gzipped.

Conclusion

When it comes to managing state updates, using Immer is a no-brainer for me. It’s a very lightweight library that lets you keep using all the things you’ve learned about JavaScript without trying to learn something entirely new. I encourage you to install it in your project and start using it right away. You can add use it in existing projects and incrementally update your reducers.

I’d also encourage you to read the Immer introductory blog post by Michael Weststrate. The part I find especially interesting is the “How does Immer work?” section which explains how Immer leverages language features such as proxies and concepts such as copy-on-write.

I’d also encourage you to take a look at this blog post: Immutability in JavaScript: A Contratian View where the author, Steven de Salas, presents his thoughts about the merits of pursuing immutability.

I hope that with the things you’ve learned in this post you can start using Immer right away.

Related Resources

use-immer, GitHub
Immer, GitHub
function, MDN web docs, Mozilla
proxy, MDN web docs, Mozilla
Object (computer science), Wikipedia
“Immutability in JS,” Orji Chidi Matthew, GitHub
“ECMAScript Data Types and Values,” Ecma International
Immutable collections for JavaScript, Immutable.js , GitHub
“The case for Immutability,” Immutable.js , GitHub

Smashing Editorial
(ks, ra, il)