React Native: Fix for “Invariant Violation: onlyChild Must Be Passed a Children With Exactly One Child”

I recently ran into a new (to me) error in React Native.

1
Invariant Violation: onlyChild must be passed a children with exactly one child

I couldn’t find any documentation on it, so I thought I’d share what I figured out.

All of the “Touchable” components in React Native do an onlyChild check on their children, which throws an error unless there’s exactly one child.

1
2
3
4
return (
  <TouchableHighlight>
  </TouchableHighlight>
); // Error: onlyChild must be passed a children with exactly one child

Adding a child to the TouchableHighlight will fix the error

1
2
3
4
5
return (
  <TouchableHighlight>
      <Text>foo</Text>
  </TouchableHighlight>
); // OK

But adding multiple children will also cause an error

1
2
3
4
5
6
return (
  <TouchableHighlight>
      <Text>foo</Text>
      <Text>bar</Text>
  </TouchableHighlight>
); // Error: onlyChild must be passed a children with exactly one child

A quick search through the React Native code reveals the components that verify onlyChild:

  • TouchableBounce
  • TouchableHighlight
  • TouchableOpacity
  • TouchableWithFeedback

Hopefully React Native can eventually provide a better message for this issue, but until then, at least this blog post should pop up when you Google the error.

React: this.state Is Undefined

I ran into this today, so I’m writing it down in case it helps someone else.

Running something like the following, I found that this.state was undefined during render.

1
2
3
4
5
6
7
8
9
class MyComponent extends Component {
  getInitialState() {
      return { count: 0 };
  }

  render() {
      return <div>{this.state.count}</div>; // Error: this.state is undefined
  }
}

After a little searching, I found the release notes for React 0.13.0-beta-1, where they explained that ES6 classes should set initial state in the constructor, rather than defining a getInitialState method.

1
2
3
4
5
6
7
8
9
class MyComponent extends Component {
  constructor() {
      this.state = { count: 0 };
  }

  render() {
      return <div>{this.state.count}</div>; // Yay, it works!
  }
}

Pretty simple, but not immediately obvious if you don’t know about it.

Configuring an Existing Octopress Site on a New Machine

Every time I set up a new machine, I have to figure out how write posts on my Octopress blog. I usually follow these instructions, but have to tweak them slightly to work for me. I fanally decided to write down the exact steps I use so I don’t have to figure them out every time. Hopefully it’s useful for someone else as well.

Step 1 – Run Octopress setup

1
2
3
4
5
6
7
git clone git://github.com/imathis/octopress.git octopress
cd octopress    # If you use RVM, You'll be asked if you trust the .rvmrc file (say yes).
ruby --version  # Should report Ruby 1.9.3
gem install bundler # On Linux/OSX you may need to run "sudo gem install bundler" instead
bundle install
rake install
rake setup_github_pages

The main purpose of setting up Octopress like this is to get the main layout configured correctly.

Step 2 – Reset to your blog’s branch tips

1
2
3
4
5
6
7
git fetch origin source
git branch --set-upstream-to=origin/source source
git reset --hard origin/source
cd _deploy
git fetch origin master
git branch --set-upstream-to=origin/master master
git reset --hard origin master

Obvious Code

A week or two ago, I got this feedback on a code review:

You’re using foo ? foo : "" here. It would be shorter and more obvious if you wrote it as foo || ""

This was valid feedback, and I updated the code.

After I’d checked in my changes, I got the following IM from a senior member of my team:

I see you did foo || ""? What does the || mean?

:)

This was a good reminder of two things:

  • “Obvious code” is a subjective concept
  • No matter how experienced you are with something, you’ll still find blind spots from time to time

P.S. If that syntax is also new to you, it’s taking advantage of how JavaScript does “or”. A JavaScript or returns the first truthy value, or the last value if none are truthy:

e.g. (false || 0) === 0 and (0 || false) === false and (foo || "") === "" (assuming foo is “falsey”)

Many JavaScript developers use this behavior as a shortcut for setting default values, because null and undefined are falsey.

Dynamically Configure Your Git Email

This post is the second in a series on tuning your Git environment. The first post on customizing your git log isn’t a prerequisite, but may be useful.

Managing Multiple Commit Emails

If you use Git at work and in your personal time, managing the email you use for commit messages can be tricky.

When my previous team first started using Git, I had several instances where I accidentally committed to our team repository with my personal email address. This wasn’t a big problem, but it made the repository history look a little messy, and it meant my picture didn’t show up properly in the UI tools.

Simple Fix: Manually Configure Email Per Repository

My first solution was to remove the global configuration for my email address:

git config --global --unset user.email

This way when I committed into a fresh repository, I’d get a warning that I hadn’t configured my email.

1
2
3
4
5
6
7
8
9
10
11
12
13
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

    git config --global user.name "Your Name"
    git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foo1

Then I just had to configure my email locally for that repository:

git config user.email will@itsananderson.com

And update the commit with the right author data:

git commit --amend --reset-author

Medium Fix: Add Some Git Aliases

Running through those steps for every new repository quickly becomes tedious, especially when you like to spin up GitHub projects for every idea that pops into your head.

To simplify things, I first created an alias for the git commit --amend --reset-author command. I called it cara for “Commit Amend Reset Author”, but you could call it whatever you’ll remember. With that alias, it’s super quick to fix a commit if I create it with the wrong author email.

The next thing I aliased was a script to guess the author email based on the repository URL. I created a script and put it in ~/.git-scripts/email-guess.sh (again, call it whatever you’ll remember).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

remote=`git remote -v | awk '/\(push\)$/ {print $2}'`
email=will@itsananderson.com # default

if [[ $remote == *github.com:Microsoft* ]]; then
  email=wiand@microsoft.com
fi
if [[ $remote == *itsananderson.visualstudio.com* ]]; then
  email=will@codeawhile.com
fi

echo "Configuring user.email as $email"
git config user.email $email

The script isn’t exactly a masterpiece, but it gets the job done. Feel free to copy and modify it to meet your needs.

For the script to be useful, I aliased it as git email-guess:

git config --global alias.email-guess \!". ~/.git-scripts/email-guess.sh" ""

So now when I clone a new repository, I just git email-guess to set the email. If I forgot to do it before my first commit, I follow it with git cara to fix that commit’s author.

Advanced Fix: Full Automation

Reducing the work of author email management to only 1 or 2 commands is nice, but I wanted to eliminate it altogether. This is where Git hooks came in handy.

You can configure a Git hook manually for each repository, but again, we want this to be automated. To do that, you’ll want to modify the template hooks Git uses when it creates new repositories.

On Windows, these hook templates are located somewhere near C:\Program Files (x86)\Git\share\git-core\templates\hooks. On OS X and Linux, they should be somewhere under the Git directory. Running which git or cat `which git` should point you in the right direction.

Once you locate the template hooks directory, create a file called post-checkout with the following contents:

1
2
3
4
5
#!/bin/bash

if [[ $1 == 00000000000* ]]; then
  git email-guess
fi

All this does is test whether Git checked out a freshly cloned repository (thus “previous SHA” is all zeros). If so, it runs git email-guess to set up the correct author email.

Wrapping Up

So that’s the full rundown of my email configuration setup. As I said in the previous post, you should take this as an example that you can customize it to fit your needs.

You can find most of my Git configuration in my git-better repository on GitHub.

As one example, there are many other Git hooks that you can take advantage of. Take a look to see if there are any that you could use to automate a frequent task.

Git

Customize Your Git Log Format

Over the last few months, I’ve been learning about woodworking in my spare time. As I’ve read articles and watched YouTube videos, I’ve noticed that the most successful woodworkers have a detailed knowledge of their tools. Not only do they know how to use and maintain the tools of their craft, but they’re not afraid to modify them to better serve their needs. When they need a custom tool or jig to speed up their work, they make one. Watching and reading about these craftsmen and their tools, I’ve noticed parallels in my full time craft: Software Development.

In the next few posts, I’ll share some of the software “jigs” I’ve created to make myself more efficient. The primary focus posts will be configuration and customization of Git.

Git Log: Your Own Personal Journal

If you’re not already aware, your Git log is a critical tool for working with source control. Because your memory’s not perfect, a good log helps you recall what you’ve done, and the motivation behind it.

I’ve written before about writing good commit messages, as has David in his series “Committed to Good Commits”. If your commit logs are sprinkled with gems like “did stuff” and “it finally works!”, you’ll want to check out those posts.

Choose Your Details With --format

Depending on what you’re looking for in your log, you may want different levels of detail. The Git log documentation has a full list of the built-in formats.

For example, if you’re trying to find the SHA for a recent change, you may just want to see the SHA and the commit subject for each commit. In that case, git log --format=oneline or git log --oneline is what you need.

If you need verbose output, including the full message and author info, --format=medium is a good option.

Finally, if you want every single detail from the commit, --format=fuller will give you that.

If you want to make any of these formats your default, you can do so with the following command:

1
git config --global format.pretty oneline # replace oneline with the format you want

Limit Results With -n

If you only want to see the last few commits, you can use the -n flag. The more verbose version is -n <number> (e.g. -n 5 to show the last 5 commits).

Alternatively, you can use an even quicker shortcut. Just use -<number>. For example: git log -5 will show the last 5 commits.

Fully Customize Your Log Output

Depending on how you use your commit log, you may find that no built-in log format exactly fits your needs. What I’ve found is that the verbose formats are too hard to scan through, and the succinct ones don’t have vital info.

To solve this problem, I created a custom log format, which I use almost exclusively.

You can configure my format with the following command:

1
git config --global format.pretty format:"%C(auto)%h %d%Creset %s%n%Cgreen%ad%Creset %aN <%aE>%n"

The output looks like this:

This format also works with the --graph flag:

What I like about this format is that it only uses three lines per commit, but it has all the information I care about. I also inserted color codes for the various parts of the message, which makes it even easier to grok.

In Conclusion

Hopefully these examples give you some ideas about what you can do to customize your commit log. Don’t feel like you need to use my custom log format as-is. The whole point is to customize it to fit your needs.

If you want to test out different custom formats quickly, you can pass them directly to git log like so:

1
git log --format=format:"%C(auto)%h %C(green)%aN%Creset %s"

You can find the different placeholder options in the same Pretty Formats section of the Git Log documentation.

Git

Netgear Nighthawk AC1900 (R7000) Review

I bought a new Wi-Fi router about a year ago, and I’ve been so happy with it that I decided to write a review.

The Goods

Netgear has a truly impressive lineup of high-quality routers in their Nighthawk series.

When I purchased the Nighthawk R7000, it was the only Nighthawk available, but now there are three options.

Nighthawk AC1900 (R7000)

This is the router I purchased. At $176, it is now the cheapest one in the series, but don’t let that fool you. It’s a beast.

Nighthawk X4 AC2350 (R7500)

This model has an additional antena, a faster processor, and boasts improved range and faster bandwidth. It costs about $100 more than the R7000. This router uses a more advanced radio than the R7000 that apparently has higher throughput and reliability. That being said, I haven’t experienced any problems with the throughput or reliability of the R7000.

Nighthawk X6 AC3200 (R8000)

This model has 6 antenas, which again boosts range and bandwidth. It also supports a third Wi-Fi band, and assigns slower and faster devices to different bands, boosting performance for fast devices. This model is only about $5 more than the R7500 ($105 more than the R7000), so if I were to upgrade, this is the model I would choose, because of it’s significantly improved bandwidth.

Price

Here’s a side-by-side comparison of the different models.

ModelPrice
Nighthawk (R7000)$176
 Nighthawk X4 (R7500)$279
 Nighthawk X6 (R8000)$283

When I first considered this router, the price was what gave me the most pause. In the past, the most I’d paid for a router was about $40, so this seemed like a significant price bump. In the end, the only reason I bought it was because a friend had bought one and was very happy with it.

After using it for a year, I don’t think I’ll ever buy a “cheap” router again. In the case of Wi-Fi routers, it seems that “you get what you pay for” holds true.

Reliability and Performance

My primary reason for upgrading my router was that my previous router, an older Linksys in the $30-40 range, didn’t reliably reach the entire house. After enough complaints from one roommate who’s bedroom was in the far corner of the house, I decided to upgrade.

After installing the R7000, I’ve stopped having router issues. The signal reaches to every corner of the house, and has never cut out.

I eventually even swapped out the Ethernet cables in my two desktop computers, replacing them with this Dual Band Wireless PCI Express adapter. Even after getting rid of the hard line, I get blazing fast speeds on both machines.

Extra Features

Mounting Slots

One of the things I took advantage of immediately was the slots on the back for mounting it on a wall. Moving the router to a more central location in my downstairs hallway provided even better coverage throughout the house.

(yes, that’s a Raspberry Pi unceremoniously dangling from the router. Don’t judge me)

Pro tip: make sure there’s a power outlet within easy reach of your desired location before you start screwing in drywall anchors :)

Web-based WPS Button

Most routers support WPS. This allows new clients to connect to a network by clicking a physical button on the router. This is convenient, but who wants to have to get up and walk over to the router.

Fortunately the Nighthawk web UI has a button you can push to do the same thing.

Easy Firmware Upgrade

Most of my past routers have had a really archaic update process. Usually you have to manually flash the firmware and go through a convoluted restart process.

The R7000, on the other hand, just requires one or two clicks to install the update and automatically restart.

And So Much More

I usually install DD-WRT on any router I buy, but the R7000 has all the features I typically use, so I’m just running the stock firmware. Here are a few of the things I use most frequently:

  • View attached devices
  • Port forwarding
  • Assign static LAN IPs
  • View traffic statistics

In Conclusion

If you’re tired of buying cheap routers that crap out after a year or two, I highly recommend the Nighthawk R7000.

A New Adventure in DevDiv

Starting Monday, I’m joining a new team at Microsoft. Even though I’m moving within the company, this will be a completely new experience, and I’m pumped.

What I’ve Been Doing

A year and a half ago, I joined a top-notch team working on a super secret Win8 app. A week after I started, our project was cancelled. Oops :)

Our team was part of the Bing Ads org structure, so after a few months of limbo, we took ownership of the management and authoring tools for display ads. Getting to work with this team of hand-picked developers has been an amazing experience. I’ve learned a ton about Agile methodologies, TDD, DevOps, and more.

I got to contribute to many projects in my time on the team, but here are the things I’m most proud of:

  • Building a RESTful API for storing, transforming, searching, and serving image and video assets
  • Building a purely static Angular SPA, backed by Node.js microservices
  • Converting most of the team’s codebase to Git on Visual Studio Online, with CI through Octopus
  • Becoming a team resource for Git and JavaScript domain knowledge

What’s Next

I’m joining the “Client Platform Tools” team inside DevDiv. They work on the TypeScript language and tooling, as well as the JavaScript tooling in Visual Studio, and the F12 tools in Internet Explorer.

I’ll be working on JavaScript profiling and diagnostics (think CPU/memory usage and network calls). This will be a new experience for me. I’ve spent most of the last year and a half writing JavaScript for either the browser or Node, but now I’ll be stepping a little deeper and working on the development tools themselves. I’ll also be jumping into TypeScript, the language in which most of the tools are written.

Thinking about everything I’m going to be learning about and working on, I’m excited, optimistic, and honestly a little scared.

But that’s good.

If changing teams didn’t move me outside my comfort zone, it’d be the wrong move.

I’ve found that there are two things that get me pumped about what I’m working on. The first is that it’s challenging. I love learning, and it turns out working on problems I don’t quite know how to solve is a great way to learn.

The second thing I love is doing work that makes a difference. I don’t only mean that in an altruistic sense, but in a broader, “makes someone’s job/life easier” kind of way. That’s why a developer tools team was so appealing to me, and why I’m so excited about what the next chapter will bring.

Ignoring JavaScript Libraries While Debugging

Debugging front-end JavaScript can sometimes be painful. When you rely on third-party libraries and frameworks, you find yourself stepping back and forth between the library’s code and your own. Most of the time, it’s safe to assume that these third-party libraries are working correctly, so ignoring them can make it easier to keep your own code in your head.

Fortunately for us, Chrome, Firefox, and Internet Explorer each provide a way to ignore library code.

Chrome

In chrome, you can ignore a specific script by right clicking it in the “Sources” tab.

You can view the currently ignored patterns in the devtools settings page.

Firefox

Firefox is similar to Chrome, but you select the script in the “Debugger” tab, and click the eye icon to “Toggle Black Boxing”.

Internet Explorer

Internet explorer uses a different term, but the concept is the same.

You can edit the exclusion list in:

%APPDATA%\..\LocalLow\Microsoft\F12\header\MyCode.json

or

%APPDATA%\..\Local\Microsoft\F12\header\MyCode.json

More info is available in the F12 tools documentation.

Unpacking a Git Database

While writing the previous post, I discovered a cool Git command which I thought I’d share.

When you clone a Git repository, most Git hosts will send you a packed version of the database. This is much more efficient than sending the raw Git objects, because duplicate content can be compressed.

However, if you want to inspect the object database with a file browser, it’s hard to do so, because the content stays packed in a single file. Unpacking is pretty simple.

If you unpack the .pack file while it’s in the .git/object/pack folder, Git won’t do anything, because it concludes that it already has all the objects contained in that .pack. However, if you move the .pack file somewhere else, you can unpack it into your repository’s database.

1
2
3
mv .git/object/pack/pack-*.pack .
cat pack-*.pack | git unpack-objects
rm pack-*.pack

And there you have it. Your packed objects are unpacked into .git/objects/ folder.

This isn’t something I recommend doing as a general practice, since it can take up significantly more space, but it’s a useful thing to be able to do if you want to manually inspect your Git database.

Git