DEV Community

loading...
Cover image for Autocompleting JSX In WebStorm

Autocompleting JSX In WebStorm

bytebodger profile image Adam Nathaniel Davis ・2 min read

Today I solved a nagging problem I've had in WebStorm for months and I figured that I'd throw it up here because it might help someone else.

WebStorm, like any modern IDE, is usually pretty impressive with its code completions. But since I switched over to more function-based components, I've experienced problems getting proper code completions when I'm adding component references in a block of JSX. Here's a tangible example of just one component that was giving me problems:

import * as PropTypes from 'prop-types';
import React from 'react';
import translate from '../functions/translate';

export default function TranslatedSpan(props) {
   return <span id={props.id} style={props.style}>{translate(props.english, props.replacements, props.translateTo)}</span>;
};

TranslatedSpan.propTypes = {
   english: PropTypes.string.isRequired,
   id: PropTypes.string,
   replacements: PropTypes.object,
   translateTo: PropTypes.string,
   style: PropTypes.object,
};
TranslatedSpan.defaultProps = {
   replacements: {},
   style: {},
   translateTo: '',
};
Enter fullscreen mode Exit fullscreen mode

Nothing too fancy here. Just a small little wrapper component that accepts a handful of props and returns a specially-formatted <span>. You can see that I'm using the well-established pattern of prop-types to define the types of props, their default values, and whether they're required.

The problem came when I tried to invoke this component somewhere else. WebStorm's autocomplete had no problem "finding" the <TranslatedSpan> component and auto-importing it at the top of the page. But for some reason, it was not doing anything to autocomplete the component's props. It looked something like this:

import React from 'react';

export default function Header() {
  return (
    <h1>
      <TranslatedSpan  {/* this is where I'd be typing */}
    </h1>
  );
}
Enter fullscreen mode Exit fullscreen mode

When I typed "Translated", WebStorm pulled up <TranslatedSpan> as an available component and autoimported it. But after the import, WebStorm did nothing else to "help" me complete the JSX for this component.

The english prop is required. But WebStorm was not auto-adding the prop into the component's JSX. When I was in the body of the <TranslatedSpan> tag, I could not get autocomplete to show me any of the props that should be available on the component.

If you google around for this, this seems to be a bit of a running issue with WebStorm. But after tinkering around with it for a while, I finally figured out how to "fix" it:

import * as PropTypes from 'prop-types';
import React from 'react';
import translate from '../functions/translate';

const TranslatedSpan = props => {
   return <span id={props.id} style={props.style}>{translate(props.english, props.replacements, props.translateTo)}</span>;
};

TranslatedSpan.propTypes = {
   english: PropTypes.string.isRequired,
   id: PropTypes.string,
   replacements: PropTypes.object,
   translateTo: PropTypes.string,
   style: PropTypes.object,
};
TranslatedSpan.defaultProps = {
   replacements: {},
   style: {},
   translateTo: '',
};

export default TranslatedSpan;
Enter fullscreen mode Exit fullscreen mode

Once I reconfigured the component as such, WebStorm's autocomplete features worked wonderfully. It appears that WebStorm wasn't "seeing" the prop-type directives that were configured below the component. But when I moved the export directive under the prop-type definitions, it fixed all of the code completions.

That stupid little bug had been driving me nuts for months.

Discussion (10)

pic
Editor guide
Collapse
stevetaylor profile image
Steve Taylor

I never noticed this problem in WebStorm when using export default function followed by declaring the prop types. I wonder if something else is causing this. I always destructured props and also used default property values instead of defaultProps.

These days I use TypeScript. Auto completion is much better.

Collapse
bytebodger profile image
Adam Nathaniel Davis Author

I agree that it might be some deeper combination of my environment/settings. I just know that when I changed the layout of the component, my autocompletion started working beautifully again. Also, I didn't bother outlining in this brief article, but I've never had this problem with WebStorm and class-based components. Just the function-based ones.

As for TS, I'm on record now as being not-a-fan. But I'll readily admit that one of the cooler benefits of TS is that is makes your autocompletion sing - in pretty much any modern IDE that you choose.

Collapse
johncarroll profile image
John Carroll • Edited

I would argue that the reason to use typescript is for the auto completion benefits--which is a non trivial, super awesome benefit. And I guess I'm also including errors like "some _____ method doesn't exist on null" under the umbrella of auto-completion.

Collapse
stevetaylor profile image
Steve Taylor

I dabbled with TypeScript since 2014 and wasn’t a fan until I had to use it in a new job this year. There’s a bit of extra setup work and it takes some getting used to, but it’s completely worth it. It has an amazing type system that fits so well with the way JavaScript is used in the real world.

Thread Thread
bytebodger profile image
Adam Nathaniel Davis Author

I would quibble over the idea that the "type system fits so well with the way JavaScript is used in the real world" (dev.to/bytebodger/key-headaches-in...), but I understand your point. 😉

Collapse
rxliuli profile image
rxliuli

react+ts+webstorm is almost perfect!

Collapse
destructor1702 profile image
Diego Vallejo

I used Webstorm in one of my previous job's around 2018 this bugs were even more common but a simple trick I found was to use airbnb's linter rules, it made all this IDE bugs go away

Collapse
bytebodger profile image
Adam Nathaniel Davis Author

Great point. Linters really help good IDEs to be great.

Collapse
fly profile image
joon

Id given up on proptypes entirely because of this issue. Time to pick it up again. Thanks a million

Collapse
bytebodger profile image
Adam Nathaniel Davis Author

Cool - I hope it helps you as well! I really like the propTypes pattern, so I keep using it, even though there are other ways to achieve the same thing.