What I learned from a React code challenge

I’m currently on hold with the Oregon Employment Department, and as a result don’t feel that I have the focus to design and implement some extra features. I’ll write a blog post instead!

An employer emailed me and asked me to complete a code challenge: create a simple to-do list in React. You can see the todo list I built here. I would have liked to style it a bit just to show off my design and CSS chops, but I focused on implementing features and ran out of time.

I’ve written todo lists in React before, but I always followed a tutorial. In this case, I kept honest and wrote everything from scratch. Without someone guiding me, it took longer than I expected, but I learned an awful lot more! I found myself really enjoying this challenge.

I probably made some beginner mistakes, and implemented some anti-patterns. If you notice any in my code, I’d love to know about them.

So.

Step one was to find a React and Webpack boilerplate. I was googling around, and found plenty of super-complex, production-ready solutions. They transpiled ES6 or 7, and included hot module reloading, local dev servers, deployment scripts, and test helpers. I didn’t want any of those. I wanted something that would use Webpack to build all my JSX modules into one JS file that I could include in some basic index file I could open in my browser. So I Googled “react webpack barebones boilerplate”.

This very simple template is one of the first things to come up, which is surprising because it simply doesn’t work. Among other things, you need to include and use the React-dom module to render things to the DOM these days.

So I forked it, fixed it, and PR’d it. We’ll see if the maintainer accepts it, but now I could move forward with the challenge!

And like 70% of my time has been looking up and remembering syntax. I’ve written a fair amount of React and JSX, but I’ve written far more Ember and Angular. Generally, the “data down, actions up” philosophy makes plenty of sense. I think you can get a good sense of my workflow and thought process by looking at my commit history.

One of my first steps was realizing that React’s getInitialState() function unintuitively (to me) sets a component’s initial state.

Another important realization was that a component’s render() function is called every time the DOM is updated. For a while, I assumed it was called only once in a component’s life, but the fact that it is frequently called means that work done and defined within it is essentially dynamic.

And finally, I had to re-learn how to send actions up through the component hierarchy. I’m not using a Flux implementation here, so there’s no dispatcher involved. If an action at a low-level needs to change something higher-up, it needs to somehow invoke a function its parent passed down to it through props.

Instead of calling a prop function directly from the render, I found that delegating to a locally-defined dispatcher function (I’m not sure what the proper terminology is here) solved a lot of problems. That is to say, instead of this:

render: function() {<button onClick={this.props.addThingie}></button>}

do this:

render: function() {<button onClick={this.handleClick}></button>},
handleClick: function(e) {this.props.addThingie()}

Not only is this prettier, but it gives you more flexibility. Instead of the addThingie() function only getting access to the click event (and thus its target and its value), you can pass addThingie() anything you’d like. Possibly something from the child’s state, or something that is computed within handleClick(). You can also do more work within handleClick(), such event.preventDefault().

In my code sample, I haven’t gotten the time to implement todo editing yet, but I am now confident that I could do so! Before this code challenge, I wouldn’t have had that confidence. That’s pretty cool.

Advertisements

Leave a comment

Filed under Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s