Thinking About console.log Usage in React

Thinking About console.log Usage in React

  • 301

Thinking About console.log Usage in React.We also discussed how to improve the quality of those messages, as well as alternatives to them. Keep these in mind as you write code, and make better use of this simple but stellar developer tool.

Are you one of those overzealous users of console.log? Do you find that when you load a page with the console open, you receive what is basically the Iliad in the form of short messages, each describing various props/state for components?

If you’re like me, sometimes you just want to know everything about your components at the time. It’s easy to forget who has what props and what the value of those props may be, depending on event listeners, parent components, and the like. The same goes for state. The changes in state are not always apparent on the page, and you may find yourself lost in the logic if you’re not making good use of posting messages to the console.

However, you might have the tendency to use console.log too much. This makes it hell when your component is rendering, or if props/state change, etc. Eventually, when you open up the inspector, you have a short novel of messages awaiting you. At this point, you’re doing more harm than good. There are various ways to go about this largely self-imposed problem.

In this piece, I’m going to discuss four ways we as developers can improve and strategize our usage of this valuable, but oft overused piece of code. We’re going to touch upon each method described below:

  1. Composing specific but succinct messages
  2. Utilizing debugger or alert as alternatives
  3. Using a component/constants to selectively print messages
  4. Deciding message necessity (creation and deletion)

By utilizing these strategies, you will be able to decide where and when to print messages to the console, as well as ensure the content of those questions is of high caliber.

1. Composing Specific but Succinct Messages

I can guarantee that if you have messages that are agonizing in length, fellow developers working on your project won’t be happy with you, and you eventually won’t be happy with yourself, either. The same logic applies to messages whose content doesn’t make sense or is vague.

Keep it short and sweet

No one wants to read a novel in one console message. While there are exceptions to this rule (such as logging a component’s props, the data received from fetch, etc.), there are often ways to remedy that, described in the other strategies here. You want to keep your statements brief and to the point.

An example of what not to do would be writing messages like the following:

“ExampleComponent is rendering. Its props are as follows:”

“ExampleButton1 was clicked. This is going to change the resolved state of ExampleComponent. This means that on the next render, logic X is going to occur and we should see ExampleComponent2 added in the body.”

The first message just needs some tidying up

The first message isn’t terrible but can be shortened up. Something like “ExampleComponent rendered, props:” is more succinct and gets the same idea across.

When it comes to messages printed in regards to components, I have found it helpful to explicitly state the name of the components within the message.

For example, if you have a component within a container, and your message is just the props of that nested component, that’s not going to be super helpful to you. Since they’re props, their value is going to be similar to the parent component, especially if you chose to not differentiate the names of the props.

You’ll end up confusing what belongs to what, which could lead you down a path to solve an issue that doesn’t even exist. Avoid this completely by being specific in your messages.

The second message should be reworked completely

The second message is a nightmare. It’s a bit of an exaggeration in regards to messages I’ve seen posted (and have, embarrassingly, written) in various code, but it is very much a story of tell, don’t show.

There’s no reason to have a message that long posting all the time. For one, something that long is annoying to see. Furthermore, if you see an entry of this length posted repetitively, the higher the chance that it’s going to get disregarded. A brief article on a business writing blog— appropriately titled “Scared Off by the Big, Bad Paragraph” — explores this phenomenon a little more; long bodies of contiguous text are vexing and not conducive to relaying an overall message.

It’s great that the second message is specific, but there’s too much going on there to get the point across. You’re saying A means B is going to happen, which affects C, but wouldn’t it be better to just say A is happening? This message assumes too much, as well. It would be great if everything in it happened as it stated, but we all know too well that even the simplest logic can go awry (missed parentheses, anyone?)

There are various remedies for the second message. It sounds like a button is being clicked and state is going to change, so let’s just say that.

“ExampleButton clicked, change state.resolved to true.”

If ExampleButton isn’t being reused elsewhere, then we can already assume the state being changed is that of its container (ExampleComponent in this case).

Secondly, we can completely omit the part about logicX if we so desire. It sounds like if ExampleComponent.state.resolved === true, then ExampleComponent2 is going to be added. That’s relatively simple, and may not even be worth mentioning.

Lastly, we don’t want a message predicting what’s going to happen within our app, we want to know what’s actually going on. If ExampleComponent2 is going to be appended, this can be shown in a couple of different ways. If it’s an explicit element of some sort, you don’t really need to log that it was added — you should see it on the page. If the element is more subtle, perhaps even barely noticeable depending on its purpose, we should have a message that fires when it renders, so we know that it did.

I’m aware of the irony of writing at length about a long console.log entry, and I’m also aware that by breaking down this message into smaller segments, one could argue that I’m creating more of them per capita. However, consider that these additional messages are now conditional — they should only show up when necessary, rather than as that behemoth of text we saw beforehand. Additionally, as previously stated, their necessity may even be moot at this point. If that’s the case, then we need not have them at all.

2. Utilizing Debugger or Alert As Alternatives to console.log

This is image title

Consider that debugger or alert might be more appropriate for information retrieval (Image source: Matt Cummings)

debugger and alert are two other tools developers can utilize in their quest to display certain data. While a bit more niche in their usage for this purpose, I believe that they shouldn’t be overlooked.

Use debugger to progressively check the value of data

debugger is great when you simply want to pause a process for whatever reason. It stops JavaScript in its tracks and gives you access to everything going on in that moment.

A great example of its usage would be in the middle of some long function. Let’s say your function takes multiple arguments or defines its own variables, etc. Instead of logging these parameters, it’s often better to stop and evaluate them as things start getting into gear.

This is doubly valuable when the values of these arguments/variables change. Because you can use debugger as many times as you want, you can pick and choose where to start and stop a process. This lets you evaluate the modification of data in a progressive format. It makes bugs and errors much easier to pin down rather than just letting the function run its course while printing various things to the console along the way.

The use of debugger can greatly reduce your use of console.log, depending on where you use it. It’s ideal for when there’s a lot going on and you want to analyze things at specific points. Since you can call upon console.log at these points, you can eliminate a lot of unnecessary junk from printing while your app is running.

Use alert to make you notice a particular piece of data

Using alert in lieu of console.log is a little more niche, but it still has its uses. It’s great for showing yourself error messages or getting the value of a piece of data that you want to stand out momentarily. The cool thing about alert is that it’s kind of like debugger in a way — it’s going to make you acknowledge something before you can get on with using the page.

That being said, it’s a little more difficult to decide where to use this in your code, if at all. It’s up to you to decide what you find important enough to be alerted on the page. With this in mind, it’s a good idea to try and use it for data that you might miss otherwise but still want to log in some way. By forcing yourself to look at the alert, there’s less of a chance that you’ll disregard its contents.

As with console.log, if you use too much of this, you’ll end up frustrating others working on your project as well as yourself. Try to alert sparingly, in cases where you really need to remind — or dare I say, alert— yourself to an important piece of information or event occurring within your app.

3. Using a Component/Constants to Selectively Print Messages

This is image title

While in many cases developers will log messages as soon as a component renders, this can lead to a barrage of messages, especially in instances of nested components. If you have each component fire off a message when it renders, your message count can easily spiral out of control.

During my time in making my most recent application, I ran into this exact scenario. It was quite literally a case of too much information, and after the umpteenth time it happened, I had an idea: why not make a simple button to manage my console.log activity? A button with an event listener to fire off messages is an easy-to-code solution.

Before we get into the assembly of said button, it is important to note that I used it mostly for state and props. While there are certainly other things one could use such a button for, state and props messages were my primary overabundance issue. That being said, this is a good time to look at what messages you are witnessing most frequently and base your logic on that.

We will discuss two ways this button can be made: via a component, or the faster but sloppier way of utilizing constants.

Creating a button component to console.log state/props

I’m not going to bother with detailing the creation of the component here, as it’s something I assume you know how to do already. Instead, let’s focus on what it will look like as an end product:

<button onClick={() => showPropsOrState()}>Console.log props/state for {props.pCompName}</button>

We create a button whose onClick fires off a callback function, showPropsOrState.

I have a repo you can see on GitHub for the code used to create such a component. I’ll go over its creation in a future piece; for now, just recognize it can receive a component’s name, state, or props, and then log them depending on what was given.

Using this button serves as a way to free up what’s going to print to the console in any subsequent renders. However, you may find yourself not wanting to be bothered to build your own component, even if it’s something that won’t take that much time. In this case, you can either look through React libraries to find a component you need (shameless plug: like mine once I make it official), or do something a little junky, but simple.

Using constants, but with less DRY code

What I did before making the above component was add functions to my constants.js file, like this one for showing props:

const showProps = (component) => {
    console.log(`${component.constructor.name} component props`, component.props)
  }

Consolelogarticle-showProps-constant

I have a similar function for showing off the state of a component. We can then create button elements in various components and utilize this function as their onClick callback.

This has several drawbacks. First off, it really only works for class components because that’s all I needed to use it for. Secondly, the creation of multiple button elements doing the same thing isn’t really DRY at all — wouldn’t it just be easier to create or utilize an already existing component from React’s library?

In spite of those, importing constants can be easier and faster if you want to print messages to the console like this, but they’re very much a patch solution. Try to utilize components for this purpose for DRYer, more flexible code.

4. Pinpointing Necessary Usage and Eliminating Unneeded Messages

This is image title

This last method is the easiest of the bunch, subjectively. However, that subjectivity is of the essence — only you can decide when to utilize console.log This also includes knowing when to get rid of messages that are no longer needed.

When it comes to deciding whether or not to implement a log, consider why you want a message to be printed in the first place. For example, if you just have a sentence claiming that the component mounted, explore why you care about that. In some areas, it might be good to know what life cycle method is occurring and when. However, it might be completely unnecessary in others. Doing this for every component creates a large, unorganized mess. Applying this logic, you can save yourself a lot of trouble in the long run if you consider your reasoning for a brief moment rather than just doing something out of habit.

That being said, there will come a time where some messages aren’t needed any longer. You may have solved a bug or gotten the information you needed at a certain point. After that, you have unneeded bloat in your code that’s just going to get in your way.

I can understand the trepidation of deleting these from your code, but this code literally takes two seconds to type out. If you’re not sure that one of them should be taken out entirely, comment it out and then evaluate its use again later. That’s not to say you should prolong getting rid of them, though. At some point, you need to be free of them entirely.

Conclusion

By the time you’ve gotten to this point in the piece, we have reflected on various simple methods and strategies that we can use to reduce the number of messages we print to the console. We also discussed how to improve the quality of those messages, as well as alternatives to them. Keep these in mind as you write code, and make better use of this simple but stellar developer tool.