Blog logotrial and stderr

react

A 4 post collection


Enums in React

 •  Filed under react, javascript

I wrote a component that held an Enum, made in the popularly-recommended fashion, as state:

const MyEnum = Object.freeze({
    FOO: Symbol('foo'),
    BAR: Symbol('bar'),
})

class MyThing extends Component {
  constructor(props) {
    super(props)
    this.state = { enumValue = MyEnum.FOO }
  }
  
  render() {
    return({
      this.state.enumValue === MyEnum.FOO ?
        <p>I pity the foo</p> :
        this.state.enumValue === MyEnum.BAR ?
          <p>I pity the bar</p> :
          <p>I pity myself</p>
    })
  }
}

and suddenly my app was breaking on hot-reloads, and I had written pitiably broken code! It seemed like the state was somehow becoming invalid whenever a hot reload happened.

This is because the hot reloader preserves the state, but every time the component is reloaded, our ES6 engine generates a new unique value for each Symbol, so the comparison this.state.enumValue === MyEnum.FOO is comparing an old value of MyEnum.FOO to the current one, yeilding false. So use an enum with deterministic values, like, say,

const MyEnum = Object.freeze({
    FOO: Symbol.for('foo'),
    BAR: Symbol.for('bar'),
})

Testing NextJS getInitialProps with Enzyme

 •  Filed under nextjs, enzyme, react

If you're using NextJs, you probably want to test getInitialProps on your pages. You can call it from your un-instantiated imported class, and use the props it returns to instantiate an Enzyme wrapper. Here's a nice little pattern:

import { shallow } from 'enzyme'
import MyPage from '../components/my-page'

describe('My Page', () => {
  var wrapper
  
  beforeEach(async () => {
    const props = await MyPage.getInitialProps()
    wrapper = shallow(<MyPage {...props} />)
  })
})

Getting set up to test React

 •  Filed under react, testing

There's a bunch of guides telling you how to do this painful-looking JSDOM setup stuff. You probably don't need it. Use Enzyme's shallow rendering, which doesn't require a DOM to mount on. As this smart guy suggests, you can call lifecycle methods yourself to emulate mounting.

This is the best practices guide you're looking for.

Check out this mess of test boilerplate. This looks awful. Don't do it. You don't need it.

Reactstrap and React 16

 •  Filed under react

Starting a new NextJS project, I was getting errors like

TypeError: Cannot read property 'toLowerCase' of undefined
  at ReactDOMServerRenderer.renderDOM (/Users/bistenes/Code/project/node_modules/react-dom/cjs/react-dom-server.node.development.js:2776:27)

and

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in.

which were obviously totally irrelevant to the actual problem. Turns out Reactstrap <5.0 is incompatable with React 16.

npm i --save reactstrap@next fixed it.