Lessons about React, Keyboard Input, Forms, Event Listeners and Debugging

Keyboard Controls

document.body.addEventListener('keydown', handleKey);

Yesterday’s Bug

keyHandler = event => {
event.preventDefault();

// Respond to the input
}

The Problem

A screenshot of my tetris app’s game over screen. There is a form to input a nickname and submit score to the leaderboard.
My leaderboard form. Typing in the nickname field had no effect.
function LeaderboardForm(props) {
const [nickname, setNickname] = useState('');

...

return (
<form>
...
<input value={nickname} onChange={setNickname} />
...
</form>
);
}

export default LeaderboardForm;

The Fix

useEffect(() => {
if (props.playing) {
document.body.addEventListener('keydown', props.keyHandler);
} else {
document.body.removeEventListener('keydown', props.keyHandler);
}
}, [props.playing, props.keyHandler]);

Consider Every Case

Lessons Learned

  • Key presses can trigger many different actions. As soon as there are several different actions triggered by the same key, we need to be very careful about how they interact. A few weeks ago, I thought adding keyboard controls would just be boring plumbing. Today, I spent enough time on this bug that I decided to write a blog post.
  • I could have identified the problem sooner. The bug appeared after I made two relatively small changes yesterday, so it seems almost certain that those changes caused it. That could have helped focus my efforts. Even in the context of more complex change history, there are tools to help.
  • Testing is important. If I had perfect, comprehensive tests, I could have identified this bug yesterday, when it first introduced, before it was committed. But that doesn’t mean testing is perfect. My bug had no effect when the form component was rendered in isolation; a simple unit test would not have helped. While my tests in this project are admittedly sparse, I doubt an automated test of whether a particular text input element displayed text typed into it within the context of the rest of the app would have been near the top of my list.

--

--

--

https://alexbostock.co.uk

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Any FrameWork before ReactJS is a myth?

01 Create first Angular project

JavaScript Best Practices — Loops and Returns

UltraTech | TryHackMe write-up

Add Charts into Our React App with Nivo — Funnel Chart

Vuetify — Carousel Customization

How to Use Async and Await with Vue.js Apps

Cluster Module : Node JS

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alex Bostock

Alex Bostock

https://alexbostock.co.uk

More from Medium

Write a simplified version of React to fully understand the fiber architecture

How to Make an Image Search App in React using the Unsplash API

How does React.memo() work? — React source code walkthrough 14

Implementing Google Fonts into your React project using Styled Components