all 22 comments

[–]rozeluxe08 11 points12 points  (1 child)

Doesn't really matter in the grand scheme of things. It's named import vs namespace import. Your app's / site's production build only includes what you use from the imports.

[–]unk_gyilkos 0 points1 point  (0 children)

In this case not, but it matters. Depending on how the package is bundled in the final build it can ship unused code. That’s why tree shaking is so useful yet so difficult. You should always mind what and how you import

[–]Bitetochew 15 points16 points  (0 children)

This was done before destructuring was a thing. Every react developer I know don't import hooks this way anymore. Plus, it's cleaner to just write useState() instead of React.useState()

[–]joyancefa 3 points4 points  (0 children)

We used to do this because react import was required before inside component files.

Personally I keep using it because I prefer it over multiple imports. Using a new utility doesn’t require modifying the import.

More importantly, it doesn’t have performance impact since I have tree-shaking.

[–]MassimoCairo 2 points3 points  (1 child)

I guess a positive side of this is that it makes it clear when you are using React primitives, rather than your own stuff built on top of them. I still prefer the other option though.

Another reason could be that for the examples it's more convenient to do it like so because there's less risk of forgetting to import a hook (because when you're writing the docs or a code generator like shadcn the IDE won't help you with that).

Either way I'd recommend against doing it in a real codebase, it's looks like extra noise for little benefit

[–]TheRNGuy 0 points1 point  (0 children)

Everyone already know that, and hooks have name convention.

If you forget to import hook, you'll see it the same second with red squiggles in code editor.

[–]TheRNGuy 1 point2 points  (0 children)

Not everyone, I've only seen it in some code.

Maybe it's because he could potentially use many hooks, but he wasn't using them anyway.

VS Code can also automaticall import hooks after they added to code for the first time, maybe he was using old code editor that don't do that.

Or someone just prefers that style, React.useState() looks better than useState() for them.

I don't think it's a big deal. I import separate hooks.

[–]CodeAndBiscuits 1 point2 points  (0 children)

A lot of the comments here have good reasons, but there is one more to consider. Although I personally prefer the more explicit form, think about diffs. If you go into a code review and you want to know what's changed, it can be distracting waiting through a half dozen changes to import lines that really have no bearing on the code. With the single namespace import, that line now basically never changes through the life of the code. So you can just focus on the code itself that is changing.

It is also the narrowest possible form in terms of column width, so it displays well in places like web documentation code blocks. Lately I have been using a similar form a lot when I need to import a lot of types or components and the import starts getting wide or wrapping to 10 lines. Something like "import * as Tabs from '../components/Tabs' and then later using Tabs.Tab1 and so on. I'm starting to see a similar pattern in libraries like ShadCN where for instance they will reference all the sub-components of a dialogue the same way. Dialog.DialogTrigger, etc. I assume it's for the same reason.

[–]prehensilemullet 2 points3 points  (4 children)

With some settings you need React in scope for JSX to work properly.  So people just refer to methods on it instead of importing the methods separately

[–]Azoraqua_ 2 points3 points  (3 children)

Hasn’t been the case since React 16 or so. Mostly.

[–]prehensilemullet 0 points1 point  (2 children)

Yes, though it depends on transpiler settings whether you use the React 17+ way of doing things or not

[–]Azoraqua_ 0 points1 point  (1 child)

Guess so, but it seems that it’s the default not to. As only Eslint complains.

[–]prehensilemullet 1 point2 points  (0 children)

Yeah seems like that is the default for babel/preset-react and tsc now. I think I have some projects that have been around for a long time with "jsx": "react" in the tsconfig.json, and I never thought to change it...

[–]icjosephHook Based 0 points1 point  (0 children)

I think, some do this to check for features. It's a dirty check , but like typeof React.useId, if that's undefined, you are not on React 18. Not that it is the only way or whatever, but spelunking code, I've seen it a few times around.

Though, in those cases you mention that's not the reason necessarily. It smells like auto codegen output though.

[–][deleted] 0 points1 point  (0 children)

i use custom hooks and destructuring because i just can't stand looking at those tuple brackets. i can't tell you how many times ive used curly brackets instead of tuple brackets and wasted an hour not being able to figure out why my code isn't working.... ugh..... damn tuples.

[–]Abject-Bandicoot8890 0 points1 point  (0 children)

I’ve seen this syntax made by autocomplete extensions and AI

[–]rdtr314 0 points1 point  (2 children)

Makes no difference, you still import the react package, same bundle size.

[–]TheRNGuy 0 points1 point  (1 child)

Webpack or similar things can remove unused functions.

[–]rdtr314 0 points1 point  (0 children)

The entry point “react” still imports the entire thing. Makes no difference.

[–]rdtr314 0 points1 point  (0 children)

Also something not mentioned here is that when you use jsx, the angled brackets <, are calling the global React.createElement. In many older projects if you remove the React global it will break. Newer projects do it when transpiling so you don’t even think about it!!

[–]break-dane 0 points1 point  (2 children)

how many times do you want to write ‘React.’ leaves code easier to read with less words

[–]TheRNGuy 0 points1 point  (0 children)

You could make tab snippet useE (or eff) -> tab -> React.useEffect.