Why I Love React 16

Fragments are the feature I intuitively expected in React 15.

They are a really welcome addition to React 16.

This is now valid:

{wantingToResume && [<hr/>, <ResubscriptionContainer />]}

Notice that the horizontal rule, and a full component are being returned inside an array.

The official announce post has another example.

I love React. Thank you to everyone involved in getting this new release out of the door, and thank you to everyone in the React community for making my time with the front end a heck of a lot more enjoyable than it used to be.

An issue with React Widgets DateTimePicker

When you have the fix to a problem, but don’t know the root cause of why that problem is happening, you have two choices:

  1. Accept you have a solution, and move on, or;
  2. Accept you have a solution, and figure out the cause of the problem.

The problem is, #2 takes time. And that might not be time you have currently.

Dwelling on some problems is not the best use of my time in my current position.

So here’s my problem, and a solution, but I cannot offer you the root cause to this problem. Nor is it the defacto solution, I believe.

Using React Widgets DateTimePicker

I guess you’re either the kind of developer who creates everything themselves.

Or you first try using other people’s.

I wanted a Date Picker, ideally with time, and I would like it to be hooked up to Redux Form.

The good news, Redux Form already works nicely with React Widgets. See the previous link for a decent tutorial. And this code sample.

As a result, I can quite easily add in a Date Time Picker that’s hooked up to my Redux Store. This is good. It pleases me.

It also allows me to start laser focusing my A/B tests.

date-of-birth-as-a-timestamp
You’ve never A/B tested unless you know for sure customers don’t prefer timestamps.

But joviality aside (wait, that was humour?), I did hit a problem along the way:

react-widgets-calendar-size-issue
That’s not so good, Al.

There is a quick fix to this.

Add in a local (S)CSS style:

.rw-popup-container.rw-calendar-popup {
  width: 24em !important;
}
redux-form-datetime-picker-react-widgets
Better

It’s good, but it’s not quite right. Good enough for me to continue, though has been firmly lodged into the ticket queue under ‘improvement’.

Here’s what it should look like:

react-widgets-datetime-picker-proper

So there you go. Hope it helps someone. It’s unofficial. It’s not the real fix. Any pointers appreciated.

How I Fixed: uncaught at check call: argument [object Promise] is not a function

Earlier this month I started dabbling with Redux Sagas as an alternative to Redux Thunks.

At the time I was highly skeptical – largely around whether re-writing a significant portion of my JavaScript was good use of my time, given that I had no prior experience with generators, and that conceptually sagas sounded pretty hard.

But I kept hitting issues with Thunks. They just seemed so cumbersome, and error prone. I found writing tests for them to be painful, and adding in the Redux API Middleware made that even more complicated.

Ultimately, switching to Redux Saga has been one of the highlights of my current project. I love it. Every problem I have had so far has been made easier through the use of sagas.

But today I hit on a problem I haven’t seen before:

uncaught at check call: argument [object Promise] is not a function

This is a generic version of the code I am using:

export function *doRequestProfile(action) {

  try {

    yield put({
      type: types.REQUEST__STARTED,
      payload: {
        requestFrom: 'my-saga'
      }
    });

    const profile = yield call(api.fetchProfile(action.payload.accountId));

    yield put({
       type: types.PROFILE__SUCCESSFULLY_RECEIVED,
       payload: {
         profile
       }
    });

  } catch (e) {

    yield put({
      type: types.PROFILE__FAILED_RECEIVING,
      payload: {
        message: e.message,
        statusCode: e.statusCode
      }
    });

  } finally {

    yield put({
      type: types.REQUEST__FINISHED,
      payload: {
        requestFrom: 'my-saga'
      }
    });

  }
}

export function *watchRequestProfile() {
  yield* takeLatest(types.PROFILE__REQUESTED, doRequestProfile);
}

I have highlighted the problematic line.

The issue here is that the error in the browser is fairly cryptic. It took me digging into the source code to figure this one out.

But actually the issue is really simple to fix.

The highlighted line above should be :

const profile = yield call(api.fetchProfile, action.payload.accountId);

I was calling my function myself, and then passing the promise on to the Saga… whoopsie daisy.

7 things I learned adding Jest to my existing JavaScript boilerplate

Here are 7 things that I encountered when trying to add Facebook’s Jest to my existing React JS project.

This project was initially based on Corey House’s boilerplate – React Slingshot. There was nothing wrong with the test setup the boilerplate provided. I just wanted an excuse to try Jest.

1. Jest doesn’t play well with importing stylesheets

Here was the code I was using:

import React from 'react';
import '../styles/about-page.css';

const AboutPage = () => {
  return (

And the associated Jest output:

 FAIL  __tests__/components/AboutPage.react-test.js
  ● Test suite failed to run

    /home/chris/Development/react-registration-demo/src/styles/about-page.css:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){.alt-header {
                                                                                             ^
    SyntaxError: Unexpected token .
      
      at transformAndBuildScript (node_modules/jest-runtime/build/transform.js:284:10)
      at Object.<anonymous> (src/components/AboutPage.react.js:2:27)
      at Object.<anonymous> (__tests__/components/AboutPage.react-test.js:2:44)

To be fair, the output looks a bit nicer in the terminal.

Removing the stylesheet line:

import React from 'react';
// import '../styles/about-page.css';

const AboutPage = () => {
  return (

Now commented out, all passing:

 PASS  __tests__/components/AboutPage.react-test.js
  ✓ Can see header (10ms)

Snapshot Summary
 › 1 snapshot written in 1 test suite.

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 added, 1 total
Time:        1.077s
Ran all test suites.

2. Tests live in the __tests__ directory

The tutorial link doesn’t make it immediately obvious that the location and naming of your test files has an assumptive default config:

(/__tests__/.*|\\.(test|spec))\\.(js|jsx)$)

The boiler plate I am using has the test files in the same directory as the component itself. I followed the boiler plate pattern first, and it didn’t work.

I was confused why my tests wouldn’t run:

> jest

No tests found
  50 files checked.
  testPathDirs: /home/chris/Development/react-registration-demo - 50 matches
  testRegex: (/__tests__/.*|\.(test|spec))\.jsx?$ - 0 matches
  testPathIgnorePatterns: /node_modules/ - 50 matches

Tests need to go in a __tests__ directory, unless you are a regex ninja.

If you do want to overwrite it then you can update your package.json with extra config:

  "jest": {
    "testRegex": "your regex here dot star hash"
  }

I went with their defaults.

Now also note, you wouldn’t have this problem if you had read the landing page and the Docs link. I made the mistake of going direct to the Docs link via Google.

3. You may need to rename things

In React so far I have seen files named like either thing.jsx,  or thing.js. I’ve never seen anyone use thing.react.js.

However, the Jest docs use this convention.

So, having made two mistakes already, I made the switch myself.

Tangible benefit: None(?)

4. Jest ran existing tests just fine

This one threw me.

I had an existing file left over from my purge of the boilerplate demo site. I manually deleted the files as I worked my way through and replaced the boilerplate parts with my own.

One such file that was left was a utility class called mathHelper.spec.js 

Jest ran this just fine:

> jest

 PASS  __tests__/components/AboutPage.react-test.js
 PASS  src/utils/mathHelper.spec.js

Test Suites: 2 passed, 2 total
Tests:       13 passed, 13 total
Snapshots:   1 passed, 1 total
Time:        1.157s

5. Snapshot Testing is a really smart idea

You are kidding me.

Another concept to learn?

When will this learning ever end? Never. Get reading.

Actually though this is fairly simple to understand, and incredibly beneficial.

An example illustrates it best.

Let’s say I have a very basic component:

import React from 'react';

const AboutPage = () => {
  return (
    <div>
      <h2 className="alt-header">About</h2>
      <p>Who wouldn't want to know more?</p>
    </div>
  );
};

export default AboutPage;

And a really simple test:

import React from 'react';
import AboutPage from '../../src/components/AboutPage.react';
import renderer from 'react-test-renderer';

test('Can see header', () => {
  const component = renderer.create(
    <AboutPage />
  );
  let tree = component.toJSON();
  expect(tree).toMatchSnapshot();
});

The first time I run the tests with npm test then Jest will create a snapshot of how this page is expected to look:

exports[`test Can see header 1`] = `
<div>
  <h2
    className="alt-header">
    About
  </h2>
  <p>
    Who wouldn\'t want to know more?
  </p>
</div>
`;

And the test output:

> jest

 PASS  __tests__/components/AboutPage.react-test.js
  ✓ Can see header (9ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 passed, 1 total
Time:        0.827s, estimated 1s
Ran all test suites.

Then, should you make a change to your component in some way which causes the output to change:

import React from 'react';

const AboutPage = () => {
  return (
    <div>
      <h2 className="alt-header">About</h2>
      <p>Changed</p>
    </div>
  );
};

export default AboutPage;

Then re-run:

> jest

 FAIL  __tests__/components/AboutPage.react-test.js
  ● Can see header

    expect(value).toMatchSnapshot()
    
    Received value does not match stored snapshot 1.
    
    - Snapshot
    + Received
    
      <div>
        <h2
          className="alt-header">
          About
        </h2>
        <p>
    -     Who wouldn't want to know more?
    +     Changed
        </p>
      </div>
      
      at Object.<anonymous> (__tests__/components/AboutPage.react-test.js:10:16)
      at process._tickCallback (internal/process/next_tick.js:103:7)

  ✕ Can see header (11ms)

Snapshot Summary
 › 1 snapshot test failed in 1 test suite. Inspect your code changes or run with `npm test -- -u` to update them.

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   1 failed, 1 total
Time:        1.078s
Ran all test suites.
npm ERR! Test failed.  See above for more details.

Again, it looks nicer in the console.

6. You probably want an alias for updating snapshots

Here’s what I use, feel free to differ:

  "scripts": {
    "test": "jest",
    "testu": "npm run test -- -u",
  },

Every time you make a change to your component you likely need to re-update your snapshots. Having an alias is better than the alternative of typing out morse code.

7. There are concerns I only found out about after reading the Snapshot announcement blog post

Dropped in at the bottom of the blog post announcing Snapshot testing is some notes about forthcoming improvements.

This one caught my eye the most:

  • Mocking: The mocking system, especially around manual mocks, is not working well and is confusing. We hope to make it more strict and easier to understand.

Thankfully I did this migration on a new git branch 🙂

How I Fixed: Redux Form onSubmit Proxy Object

It’s late, I’m tired, but no excuses, this took me about 45 minutes to figure out even with the documentation.

The problem:

I wanted to use Redux Form (v6.0.5) to handle form submissions for a simple login form.

I could get the form to render, and submit, but when I submitted my data, rather than getting back the JSON data as expected, instead I got a funky proxy object:

Proxy {dispatchConfig: Object, _targetInst: ReactDOMComponent, _dispatchInstances: ReactDOMComponent, nativeEvent: Event, type: "submit"…}

Annoyingly now I cannot reproduce the issue that made the Proxy object appear in the first place, but here is sample working code that fixed the issue:

import React, { Component } from 'react';
import LoginForm from '../components/LoginForm';

export default class LoginPage extends Component {

  doLogin(formData) {
    console.log('Submitted form data', formData);
  }

  render() {
    return (
      <div>
        <LoginForm onSubmit={this.doLogin}/>
      </div>
    );
  }
}

And the login form itself:

import React  from 'react';
import { Field, reduxForm } from 'redux-form';

const LoginForm = (props) => {

  const { handleSubmit } = props;

  return (
      <form onSubmit={handleSubmit}>

        <label htmlFor="username">Username</label>
        <Field component="input"
               type="text"
               name="username" />

        <label htmlFor="inputPassword">Password</label>
        <Field component="input"
               type="password"
               name="password" />

        <button type="submit">Sign in</button>

      </form>
  );
};

LoginForm.propTypes = {
  onSubmit: React.PropTypes.func.isRequired
};

// Decorate the form component
export default reduxForm({
  form: 'login' // a unique name for this form
})(LoginForm);

There is a section on this in the documentation, but for the life of me, I couldn’t get my head around it.

All I know is, it seemed to like it more when I switched my LoginForm from a class to a function. But as I say, when I tried to revert my changes back to write up this blog post, it worked as a class all the same.

Hopefully this saves someone some time in the future.