Today I Learned

A Hashrocket project

563 posts by joshbranchaud @jbrancha

Create An Object With No Properties

When you call new Object or even just instantiate an object with {}, you are creating an object that uses the Object prototype. This means it inherits from Object.prototype.

You can deliberately create an object with no properties by making sure that it does not inherit Object.prototype.

> const propertylessObject = Object.create(null);
{}

> propertylessObject.__proto__
undefined

Unlike most objects that we encounter as we write JavaScript, this object we created with Object.create(null) has no properties including no __proto__.

See Object.create and Object.prototype for more details.

Allow HTTPS Through Your UFW Firewall

UFW — Uncomplicated Firewall — is just what is sounds like. I have it running on a DigitalOcean box and it is only letting through traffic on ports 80 (HTTP) and 22 (SSH). I am setting up SSL for a domain hosted on this box which means I need to also let through traffic on 443 (HTTPS).

The allowed ports can be checked with the status command:

$ sudo ufw status

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx HTTP                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx HTTP (v6)            ALLOW       Anywhere (v6)

As we can see, HTTPS has not yet been allowed by ufw. We can allow HTTPS traffic with the allow command.

$ sudo ufw allow https

Check the status again and see that HTTPS is now included in the list.

source

h/t Dillon Hafer

Turn Off Console Error Messages In A Test

I’m using Jest to test a React component that requires a prop via PropTypes. In one of my tests, I want to test that component when the required prop is excluded. The side effect of doing this is that my test output gets cluttered with the PropType warning.

The thing to do is silence the error message during that test.

it('renders a component without a required prop', () => {
  const originalError = console.error;
  console.error = jest.fn();

  // test code here
  expect(shallow(<My Component />)).toDoSomething;

  console.error = originalError;
});

We can silence console.error by temporarily replacing it with a Jest-mocked function and then putting it back at the end of the test.

Spelunking Through Components With Enzyme's Dive

Most of the components we write have other components nested in them.

const Hello = ({ name }) => <h1>Hello {name}!</h1>;

const HelloContainer = (props) => (
  <div>
    <Hello {...props} />
  </div>
);

If we are to shallow render the above component using Enzyme, we’ll only see things one layer deep:

const wrapper = shallow(<HelloContainer name="World" />);
// wrapper ~= <div><Hello name="World" /></div>

If we’d like to explore a particular child of the rendered component further, we can do a little find and dive.

const wrapper = shallow(<HelloContainer name="World" />);
const helloWrapper = wrapper.find(Hello).dive();
expect(helloWrapper.text()).toEqual("Hello World!");

This allows us to make pinpoint assertions about how our components render without mounting the entire thing.

See a live example here.

h/t Vidal Ekechukwu

Use React 16 With Gatsby

Gatsby, the blazing fast static site generator for React, is tied to React 15.6. If you’ve been using React 16+ for a while, then this may come as a bit of a buzzkill.

Fortunately, there is a Gatsby plugin that lets you use React 16 with a Gatsby v1 site — gatsby-plugin-react-next.

Add it the plugin as a dependency:

$ yarn add gatsby-plugin-react-next

Then add it to the list of plugins in gatsby-config.js:

plugins: [`gatsby-plugin-react-next`];

source

Add Fab Icons To Your Site With FontAwesome 5

Check out the latest version of FontAwesome.

Version 5 has been re-written and re-designed completely from scratch.

One part of the rewrite is that brand icons have been organized into their own collection. Whether you are using the full suite or just the brands bundle, you’ll be referencing these icons with the fab class name.

<i class="fab fa-react" />

This will give you a React icon.

Check out all the different brand icons here.

Avoid The Notch With SafeAreaView On React-Native

iOS devices, especially the iPhone X, have areas of the screen that are cut off in ways that present quite a challenge to developers. One of the easiest ways to deal with rounded corners and the notch when developing for iOS is to avoid them all together.

The purpose of SafeAreaView is to render content within the safe area boundaries of a device.

import { SafeAreaView, View, Text } from 'react-native';

const App = () => {
  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: "#e6e6e6" }}>
      <View>
        <Text>Safely rendered in the visible area of the device!</Text>
      </View>
    </SafeAreaView>
  );
}

The unsafe area can be styled however you like and everything inside <SafeAreaView> will be pushed into the visible area of the screen.

h/t Dillon Hafer

source

Dynamically Create HTML Elements

An HTML element can be created with a string that matches a recognized entity.

const Paragraph = 'p';
return <Paragraph>Some paragraph content</Paragraph>

This means we can dynamically create HTML elements such as headers:

const H = ({ level, ...props }) => {
  const Heading = `h${Math.min(level, 6)}`;
  return <Heading {...props} />;
};

return (
  <React.Fragment>
    <H level={1}>Header 1</H>
    <H level={2}>Header 2</H>
    <H level={5}>Header 5</H>
  </React.Fragment>
);

With some inspiration, I’ve created a live example here.

create-react-app Has A Default Test Setup File

In Configure Jest To Run A Test Setup File, I pointed to a way of configuring Jest in either the package.json or jest.config.js file with the setupTestFrameworkScriptFile value.

In a create-react-app project, this is not an option because setupTestFrameworkScriptFile is not one of the permitted config values for Jest.

There is a built-in value which happens to match what was recommended in the above post — <rootDir>src/setupTests.js.

This means that there is no configuration required. Instead, just create a setupTests.js file in the src directory of your CRA project and add any framework setup you need there. That file is already configured to run when you invoke yarn test.

source

Configure Jest To Run A Test Setup File

Jest can be configured to run a setup file before each test. This is useful for configuring your testing framework in a single place, rather than in each test file.

This setup file can be specified in package.json (or jest.config.js).

// package.json
{
  // ...
  "jest": {
    "setupTestFrameworkScriptFile": "<rootDir>src/setupTests.js"
  }
}

The setupTestFrameworkScriptFile points to a test setup file at the specified location rooted at <rootDir> (the root of your project).

This kind of setup is helpful for something like Enzyme that needs to be configured with a specific adapter for use throughout your tests.

Check If Something Is An Array

The Array class has a function on it called isArray() which can be used to check if something is an array.

> Array.isArray('Hello, World!');
// => false

> Array.isArray(['One', 2, [3]]);
// => true

> Array.isArray({ foo: 'bar' });
// => false

> Array.isArray([]);
// => true

The MDN docs provide an example polyfill if it is not natively available.

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}

Access System Information On OS X

On machines running OS X, there is an Apple icon in the upper left corner as part of the menu bar. Clicking on this icon reveals a number of options. The first reads About This Mac.

If you hold down the option key, however, that first option will instead read System information…

Select that option to access the System Information panel which can tell you details about your hardware, software, and network.

h/t Dillon Hafer

Resolve And Pass Multiple Values From A Then

Let’s say you are chaining multiple async function calls together.

fetchTrainer(trainerName)
  .then(response => {
    const trainerData = response.body;

    return fetchPokemonFor({ trainerId: trainerData.id });
  })
  .then(response => {
    // I want trainerData, but it is now out of scope...
  });

But in the last then() you want access to both the trainerData and the pokemonData. So, how do you pass both the trainerData and the resolved response of fetchPokemonFor() through to that last then().

fetchTrainer(trainerName)
  .then(response => {
    const trainerData = response.body;

    return Promise.all([
      trainerData,
      fetchPokemonFor({ trainerId: trainerData.id })
    ]);
  })
  .then(([trainerData, pokemonResponse]) => {
    const pokemonData = pokemonResponse.body;

    // do something with trainerData and pokemonData
  });

Promise.all allows us to resolve and pass multiple promises. If any of the values in the array argument is not a promise, it simply passes it through.

h/t Brian Dunn

Mocking Requests With Partial URIs Using Regex

Generally when mocking out requests with the webmock gem, we specify full request URIs like so:

stub_request(:post, 'http://localhost:4000/api/posts')

We may not want to specify the entire URI though. For instance, the host may change or be configurable. The stub_request method allows us to use regex.

stub_request(:post, %r|/api/posts|)

Using the %r regex literal syntax, we are able to avoid escaping all of the / characters in our URI.

h/t Brian Dunn

Sync Your react-router State With Redux

If you are building a React app that uses both redux and react-router, you’ll find that you are managing app state in two places. Most of your app state is in redux. The router-specific state is component-state in the Router.

You can unify it all in redux with react-router-redux.

You’ll need to apply some middleware, combine routerReducer with the rest of your reducers, and then swap out your BrowserRouter with a ConnectedRouter. You can read about the details here.

Create Dynamically Named Custom React Components

A React element is as simple as a function that returns some valid JSX. Any function will do.

const CustomComponent = ({ children }) => {
  return (
    <React.Fragment>{children}</React.Fragment>
  );
};

This function provides us with a React component that has a fixed name — CustomComponent. With the help of the displayName property, we can create dynamically named components.

const ComponentGenerator = ({ customName, children }) => {
  const CustomComponent = ({ children }) => {
    return (
      <React.Fragment>{children}</React.Fragment>
    );
  };
  CustomComponent.displayName = customName;

  return (
    <CustomComponent>{children}</CustomComponent>
  );
};

const App = () => {
  return (
    <ComponentGenerator customName="RandomComponentName">
      Hello!
    </ComponentGenerator>
  );
}

If we inspect the generated React tree, we will not see anything called <CustomComponent>, but instead we will see our <RandomComponentName> component.

Remember, React components need to have an uppercase name.

Import A Github Project Into CodeSandbox

A really fancy feature that CodeSandbox offers is the ability to import a Github project. If you go to the Create Sandbox page, you’ll see some options including Import from Github. From there, paste in the URL to a public github repository and a matter of seconds your entire project will be synced into a new CodeSandbox project.

I recently did this with a create-react-app project and CodeSandbox even knew how to recognize that it was a CRA app so that it could run and display it in the web view.

Mock A Function That A Component Imports

You have a component that relies on an imported function, isAuthenticated().

// MyComponent.js
import React from 'react';
import { isAuthenticated } from './authentication';

const MyComponent = (props) => {
  if (isAuthenticated()) {
    return (<div>{/* ... */}</div>);
  } else {
    return (<div>Not authenticated</div>);
  }
};

You’d like to test that component without having to manage the authentication of a user. One option is to mock out that function. This can be done with some help from jest.fn() and the mock.mockReturnValue() function.

// MyComponent.test.js
// ... various testing imports

import * as authModules from './authentication';

it('renders the component', () => {
  authModules.isAuthenticated = jest.fn().mockReturnValue(true);

  const wrapper = shallow(<MyComponent />);
  expect(toJson(wrapper)).toMatchSnapshot();
});

By importing the same module and functions used by MyComponent, we are then able to replace them (specifically, isAuthenticated) with a mocked version of the function that returns whatever value we’d like. As MyComponent is being rendered, it will invoked our mocked version of isAuthenticated instead of the actual one.

You could test the other direction like so:

authModules.isAuthenticated = jest.fn().mockReturnValue(false);

Access The Latest Lifecycle Methods In An Old App

With the release of React 16.3 we have access to some new lifecycle methods and are in the first phase of what will eventually result in the deprecation and removal of componentWillMount, componentWillReceiveProps, and componentWillUpdate.

You may not be ready to move your project to React 16.3, but that doesn’t mean you can’t start migrating your lifecycle methods now. We’ll need a polyfill — react-lifecycles-compat.

import React from 'react';
import { pollyfill } from 'react-lifecycles-compat';

class MyComponent extends React.Component {
  static getDerivedStateFromProps(nextProps, prevState) {
    // ...
  }

  render() { ... }
}
polyfill(MyComponent)

export default MyComponent;

For any of our class components for which we’d like to start using the new lifecycle methods, we just need to import the polyfill function and then transform the class component with the polyfill before exporting it.

source

Reach Into An Object With Nested Data With Get

Among the many lodash utilities is _.get for getting data from nested objects. You can specify where to reach into the nested data of an object using a path.

Consider the following awkwardly nested object:

const resp = {
  error: {
    errors: [
      { message: "Something went wrong" },
    ],
  },
};

Here is how we might reach into this with vanilla JavaScript:

resp.error.errors[0].message;

Reaching into this for the message value is tricky because as soon as the resp object contains differently nested data, an error is likely to be thrown. We can simultaneously avoid a bunch of exception handling logic and provide a default value with the _.get function:

_.get(resp, 'error.errors[0].message', 'Default error message');

If we decide to not include a default value, then undefined will be used.

Mock A Function With Return Values Using Jest

Jest provides a collection of utilities for working with mocked functions. To create a mock function, do:

jest.fn()

// assign it to a variable
const fakeFunc = jest.fn();

// pass it as a prop
<SpecialInput handleChange={jest.fn()} />

A mocked function can then be attributed with a return value.

const fakeFunc = jest.fn();
fakeFunc.mockReturnValue("hello");
fakeFunc(); // => "hello"

The mockReturnValue() function ensures that the value is returned whenever your function is called.

We can also limit the return value to occurring just once.

const fakeFunc = jest.fn();
fakeFunc.mockReturnValueOnce("hello");
fakeFunc(); // => "hello"
fakeFunc(); // => null

mockReturnValueOnce() ensures the value is returned once and all subsequent calls yield null.

Set A Window To Its Default Zoom Level In Mac OS X

Often when showing my screen to someone else or connecting to a project, I have to adjust the zoom level of my current window by hitting Cmd + a bunch of times. Once I am done I usually do some guess work to get the screen size back to what I am used to, hitting Cmd - a couple times.

There is an easier way.

Hitting Cmd 0 will return the window back to its default zoom level.

h/t Jake Worth

Debug Jest Tests In create-react-app

When you put a debugger; statement in one of your Jest tests and run yarn test, the test runner will ignore the debug statement and run to completion. This is because Jest defaults to parallelizing tests which won’t mix well with manual debugging intervention.

If we want to be able to run our Jest tests through a debugger. We will need two things. First, we need a debugging environment — Chrome’s devtools will work well for this. Second, we need our tests to run in band. The react-scripts documentation recommends adding a second, debug-specific test command to your package.json:

"scripts": {
  "test:debug": "react-scripts --inspect-brk test --runInBand --env=jsdom"
}

You can now run yarn test:debug which will start a paused debug session. Open chrome at chrome://inspect to access and open the debugging session panel. Now, debug away.

Configuring The Pager

When you run Git commands that produce a bunch of output, Git will use a pager to present the content starting at the beginning, rather than spitting it all out to the screen at once. This will almost always come in handy for commands like git-diff and git-log.

By default, Git uses less as its pager.

You can also choose to configure it to something else by updating your git config file or by running the following command:

$ git config --global core.pager 'more'

If you’d like to turn the pager off altogether, set it to a blank string.

$ git config --global core.pager ''

source

Building A React App In The Browser

There are a couple relatively new tools that give you just about everything you need to build a React app in the browser.

The first is CodeSandbox. It has a couple pre-configured environments for different technologies. The main one is React. CodeSandbox describes itself as such:

an online editor that helps you create web applications, from prototype to deployment.

The second, which just released out of beta, is Glitch which comes with projects like react-starter so that you can jump into a React project that is ready to roll. Glitch describes itself as:

the friendly community where you’ll build the app of your dreams

You can quickly build and publish React apps in either of these and share them with the world.

Test Coverage Stats With Jest

Jest is a delightful tool for JavaScript testing from Facebook. As your project evolves and you add tests (or perhaps choose to not add tests) you may wonder what kind of test coverage you have. What is the overall coverage? Which files are well covered and which are seriously lacking?

Use the --coverage flag to get this information.

$ jest --coverage

After running all of your tests a table will be output to the terminal with a list of files and their respective coverage percentages in terms of statement, branch, function, and line coverage.

---------------------------|----------|----------|----------|----------|----------------|
File                       |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
---------------------------|----------|----------|----------|----------|----------------|

This can help guide you to what parts of your app may need more testing.

Test Files In create-react-app

Any .js files placed in the __tests__ directory will be treated as tests by Jest when running yarn test. If you don’t want to place all of your files in that directory and especially if you want to co-located your test files with the source files, you can name them with the .test.js or .spec.js suffixes.

Any files in your create-react-app project ending in these suffixes will be treated by Jest as test files and included in test runs.

There are more details in the docs.

Enforce Specific Values With PropTypes

Being able to constrain our user interfaces to very specific values is valuable. This makes our interfaces easier to reason about and easier to test. PropTypes in general are one of the ways that we constrain our UIs. We can go even further than simple type constraints by limiting a prop to a specific set of values, an enum if you will.

MyComponent.propTypes = {
  flavor: PropTypes.oneOf(['Vanilla', 'Chocolate', 'Strawberry']),
};

The docs say about oneOf():

You can ensure that your prop is limited to specific values by treating it as an enum.

If we use MyComponent with a value such as Pistachio, we’ll have a console warning to answer for.

source

Create Listing Of All Middleman Pages

Middleman is a handy tool for quickly throwing together a bunch of static pages with layout and templating help at the ready. Once you have a handful of pages up and running, you’ll probably want a way to quickly navigate to them. You can add a quick listing of all the pages with a couple helpers provided by Middleman.

<ul>
  <% sitemap.resources.each do |resource| %>
    <li><%= link_to(resource.path, resource.path) %></li>
  <% end %>
</ul>

The sitemap.resources variable will contain a list of all the resources that get processed and served by the Middleman app. The link_to helper makes it easy to turn those into links.

Because resources includes images and other assets, you may want to filter down to just html files which could look something like the following:

<ul>
  <% sitemap.resources
       .select { |resource| resource.path =~ /html$/ }
       .each do |resource|
  %>
    <li><%= link_to(resource.path, resource.path) %></li>
  <% end %>
</ul>

Just add the snippet to whatever page you’d like the page listing to appear on.

Add React With Webpacker To A New Rails App

Webpacker makes it easy to manage app-like JavaScript in the context of a Rails app. React is a great candidate for this kind of webpack-powered JavaScript processing pipeline.

To set up a new Rails project with Webpack and React wired up, add the --webpack=react flag:

$ rails new rails-react-app --webpack=react

As part of the generated app, you will get a app/javascript/packs directory with a hello_react.jsx file that has a really basic React component.

source

Seeding And Generating Random Integers In ReasonML

It is easy enough to generate a series of random numbers using the Random module’s int function.

Random.int(10);

This will generate a random integer between 0 and 9.

You may notice that the randomness is the same each time you run your program. That is because you have fixed seed. To make sure you have a different seed each time your program runs, you can initialize the random number generator with something different at each run, such as the current time.

Random.init(int_of_float(Js.Date.now()));

See a live example here.

Scoping Variables With A Block Statement

A solid way to keep code readable and easy to understand is to ditch the terse one-liners in favor of breaking things up across multiple lines and using self-documenting variable names. This isn’t all good though. Each new variable that is defined is a handle on some data that can be misused later in the syntax scope.

JavaScript has a nice way of being clear about the scope of certain variables:

let parsedDate;
{
  let [month, day, year] = input.split('-');
  parsedDate = new Date(year, month, day);
}

// do something with parsedDate

The month, day, and year variables are scoped to the { ... } which is a block statement. This helps communicate and enforce that those variables are only to be used in that very specific context. Other developers and our future selves won’t be able to erroneously use those variables.

Of course, breaking out a function is another way of accomplishing this. Sequestering code in a different part of the file is not always the best answer though. Sometimes you want it locally fenced off. For those times, use a block statement.

Apply Styles To the Last Child Of A Specific Type

The :last-child pseudo-class is a way of specifying styling that will only be applied to an element if it is the last child among its siblings. What if we have elements that are declared amongst elements of another type? This can complicate that styling.

The styling

span:last-child {
  color: red;
}

won’t take effect on our last span here

<div>
  <span>One</span>
  <span>Two</span>
  <span>Three</span>
  <div>Something unrelated</div>
</div>

because amongst its siblings it isn’t the last.

One way of getting around this is with the :last-of-type pseudo-class.

span:last-of-type {
  color: red;
}

See a live example here.

Show The Good And The Bad With Git Bisect

The git bisect command is a powerful tool for tracking down a past commit where something verifiable about the code changed — whether it be visual or functional. After using git bisect to traverse back and forth through your commit history, you may be wondering where things stand.

The git bisect log command will show you each commit that has been inspected and whether you’ve marked it as good or bad.

These records can be handy for double checking your work if you’re worried that you made a mistake along the way.

String Interpolation With Quoted Strings

Stapling strings together with the ++ operator can be tedious and clunky. If you have string variables that you’d like to interpolate, you can piece them together much more easily using quoted strings.

We can get close to a solution with the standard quoted string syntax.

let greeting = (greetee) => {
  {|Hello, $(greetee)!|}
};

Js.log(greeting("World")); // => "Hello, $(greetee)!"

This isn’t quite right though. We have to take advantage of a preprocessing hook provided by Bucklescript. The j hook supports unicode and allows variable interpolation.

let greeting = (greetee) => {
  {j|Hello, $(greetee)!|j}
};

Js.log(greeting("World")); // => "Hello, World!"

To use this pre-processor we have to include j in the quoted string like so {j|...|j}.

See a live example here.

Get The Location And Size Of An Element

All modern browsers ship with the getBoundingClientRrect() function. It can be invoked for any DOM element. It returns the x and y coordinates of the element within the browser viewport as well as the height and width values and the top and bottom values along the y-axis and left and right values along the x-axis.

> $0.getBoundingClientRect()
{
  "x": 381.421875,
  "y": 70,
  "width": 1030.578125,
  "height": 48,
  "top": 70,
  "right": 1412,
  "bottom": 118,
  "left": 381.421875
}

For instance, this is the result of invoking it against a header element on the MDN page linked above.

A React Component Is Just A Bag Of Data

If you write enough React using JSX, it is easy to forget that you’re not working with markup. Everything — divs, h1s, 3rd party components, your components — all get boiled down to JavaScript objects full of data.

Any given React component is really just a bag of data. Try doing a console.log to see. Here is an example from an earlier post.

const ParentWithClick = ({ children }) => {
  return (
    <React.Fragment>
      {React.Children.map(children || null, (child, i) => {
        console.log(child);
        return <child.type {...child.props} key={i} onClick={handleClick} />;
      })}
    </React.Fragment>
  );
};

const App = () => (
  <div>
    <ParentWithClick>
      <span>Click this span</span>
    </ParentWithClick>
  </div>
);

Looking in the console, we see the following output:

Object {type: "span", key: null, ref: null, props: Object, _owner: Object…}
 type: "span"
 key: null
 ref: null
 props: Object
  children: "Click this span"
 _owner: Object
 _store: Object

It contains information about the component itself and because of the tree structure of this data, you could potentially expand the props —> children sections several times for certain components.

See a live example here.

Spread The Rest With ES6

The spread operator provided by ES6 is a powerful syntactic feature. One way it can be used is to capture the rest of an object or array in a variable.

const pokemon = ["Charmander", "Squirtle", "Bulbasaur"];
const [first, ...rest] = pokemon;

console.log("Remaining: ", rest); // Remaining: ["Squirtle", "Bulbasaur"]

const gymLeaders = {
  brock: "rock",
  misty: "water",
  surge: "electric",
  erika: "rainbow"
};
let { brock, erika, ...otherLeaders } = gymLeaders;

console.log(otherLeaders); // Object {misty: "water", surge: "electric"}

Using this spread destructuring we can capture the remaining parts of an array or object in a variable. We can also use this syntax in a function signature to grab specific items from an incoming object argument without losing track of the rest — this is especially useful in React.js development when dealing with incoming props.

This is a stage 3 feature and may not be available in your particular environment.

See a live example here.

Mapping Over One Or Many Children In React

In Dynamically Add Props To A Child Component, I talked about how a child element can be reconstituted with additional props. The approach I showed will only work in the case of a single child being nested in that component. What if you want your component to account for one, many, or even children?

React comes with a built-in function for mapping that handles these cases.

const ParentWithClick = ({ children }) => {
  return (
    <React.Fragment>
      {React.Children.map(children || null, (child, i) => {
        return <child.type {...child.props} key={i} onClick={handleClick} />;
      })}
    </React.Fragment>
  );
};

The React.Children.map function allows mapping over one or many elements and if children is null or undefined, it will return null or undefined respectively.

See a live example here.

Dynamically Add Props To A Child Component

If your component has an element nested in it, then it will receive a children prop. There are a number of things you can do beyond simply including the children as part of the rendered output of the component. One thing you can do is put additional props on the child.

const ParentWithClick = ({ children }) => {
  return (
    <children.type
      {...children.props}
      onClick={() => alert("You clicked me!")}
    />
  );
};

This ParentWithClick component will reconstitute its child component with its given props and a new onClick prop.

Here is how it can be used:

const App = () => {
  return (
    <ParentWithClick>
      <span>Hello!</span>
    </ParentWithClick>
  );
};

Click on Hello! and you’ll see the alert.

Minor caveat: multiple children and a string child will need to be handled differently.

See a live example here.

Who Is Your Favorite Child?

When we put some content inside the open and close tags of one of our components, we get access to it as the children prop.

const Parent = ({children}) => {
  return (
    <React.Fragment>
      <p>These are my favorites:</p>
      {children}
    </React.Fragment>
  );
}

const App = () => (
  <div>
    <Parent>
      Greg and Marsha
    </Parent>
  </div>
);

What happens if we also provide an explicit children prop to Parent?

const App = () => (
  <div>
    <Parent children={"Jan and Peter"}>
      Greg and Marsha
    </Parent>
  </div>
);

Which will take precedence when we destructure children in the parent component?

In the example above, we’ll still see Greg and Marsha rendered. The content placed inside the tags will take precedence over the explicit children prop.

See a live example here.

Custom Type Checking Error Messages With Yup

In Yup Schemas Are Validated Asynchronously, I showed how to create a simple schema that allows you to enforce that a value is a number.

const numSchema = yup.number();

If we use this schema to validate something that isn’t a number, Yup will provide a lengthy default message. Here is what we get if we validate against 'hey':

this must be a number type, but the final value was: NaN (cast from the value "hey").

This value isn’t necessarily suitable for displaying to a user. We can customize the type checking error message by redefining our schema with the typeError() function:

const numSchema = yup.number().typeError("Invalid number");

Yup Schemas Are Validated Asynchronously

Yup provides a flexible object schema validation DSL. For instance, if you want to enforce that a certain value is a number, you can define something like this:

const numSchema = yup.number();

You can then validate anything against that schema.

const validator = (val) => {
  numSchema.validate(val)
    .then(result => {
      console.log(result); // it is the value of `val`
      return true;
    })
    .catch(error => {
      console.log(error.errors); // array of validation error messages
      return false;
    });
};

The validation is async, so if it succeeds the then block is hit. If the validation fails, it will fall through to the catch.

validator(5) // => true
validator('what') // => false

Build For A Specific OS And Architecture

Go programs can run anywhere, but you’ve got to create builds specific to each operating system and architecture. This can be done when building by specifying the GOOS and GOARCH environment variables.

For example, if you’d like to build a 32-bit Linux distribution:

GOOS=linux GOARCH=386 go build -o linux_386_build

The GOOS value specifies the operating system as Linux and the GOARCH value of 386 specifies a 32-bit architecture.

The plethora of GOOS and GOARCH options can be found here.

Link A JavaScript Package Locally

If you are putting together a JavaScript package and you’d like to test it out locally before putting it on NPM, use npm link.

First, from the directory of the package you are creating run:

$ npm link

This will symlink the package to the global node modules directory.

Then, from the base project directory that you want to try importing and using the package from, run:

$ npm link name-of-package

This will create an additional symlink from the global node modules directory to the node_modules of this target project.

You’ll now have access to the project, try an import to get what you need and try it out.

See man npm-link for more details.

Selecting DOM Elements Faster Than Ever In Chrome

Selecting and inspecting DOM elements: you’ve done it many times before. Whether you right click the element and select Inspect (which isn’t always all that accurate) or you use the DevTools’ inspect tool with highlight-assist, it takes a couple clicks to get there.

There is a faster way.

Hit Cmd-Shift-C.

Chrome DevTools will be expanded open if it isn’t already and your mouse pointer will be put in inspect mode with the highlight-assist. Find your DOM element, give it a click, and start inspecting!