10

I've recently started a react project and I found some util commands with npm to generate some projects automatically. No problem with that, but the project structure was a bit confusing for me so I've searched for some explanations on google, everything was fine, and I've found something interesting on https://www.pluralsight.com/guides/file-structure-react-applications-created-create-react-app:

While components can reside in src/components/my-component-name, it is recommended to have an index.js inside that directory. Thus, whenever someone imports the component using src/components/my-component-name, instead of importing the directory, this would actually import the index.js file.

This index.js file, how should I create it to return the component?

For example I want to create some pages for different routes:

import React, {Component} from 'react'
class MyPage extends Component{
  render() {
    return (
        <div>
            My Page
        </div>
    );
  }
}
export default MyPage;

Now, the index.js should look like this?

import React from "react";
import MyPage from "src/pages/MyPage";

const mypage = () => {
    return <MyPage/>
};

export default mypage;

And the project structure:

src
 |___pages
       |____MyPage.jsx
       |____index.js

And there should be no problem with the Router component because all I have to do without index.js is to import MyPage and do something like this:

<Router>
  <div>
    <Route path="/" component={MyPage} />
  </div>
</Router>

Is this the correct way to create that index.js file?

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
user1234SI.
  • 1,812
  • 1
  • 8
  • 22
  • 3
    Who told you that? There is literally nothing about React that makes this "better" or "preferred". In fact, using `index.js` for _single_ components is just clutter. If you have an index that allowed you to say `const { MyComponent, SecondaryComponent, ChildThing, AndMore } = require('./components/`);`, then sure that's useful, but for individual components this advice makes very little sense. Can you cite you source? – Mike 'Pomax' Kamermans Feb 28 '20 at 20:37
  • 2
    You don't *have* to, it just lets you control the interface of your modules more easily. And this isn't React-specific, it's general JS. – jonrsharpe Feb 28 '20 at 20:39
  • Your code and your js files are fine; about `index.js | ts | html| jsx | tsx` it is just the way every product and professional expect it, nothing special; that is the way tools and people have used to and evolved. like the "Hello World" from early programming days – Mechanic Feb 28 '20 at 20:55
  • 1
    `index.js` file acts like a container where you render all the subcomponents of the page.This helps you to split the code into smaller chunks which improves readability and testing – Prakash Reddy Potlapadu Feb 28 '20 at 21:03
  • First of all, thank you for your time, but I don't think I understand your answer. Ok, it's not a great idea to import a `Button` component from `button.js`, I understand this, but what I wanted to emphasize is *instead of importing the directory, this would actually import the index.js file* -> and my question: is react looking by default for an **index.js** file when you import the component ?? – user1234SI. Feb 28 '20 at 21:12
  • Oh.. now it makes sense.. Thank you again for your time, now I understand what you wanted to say and what I misunderstood from plural sight: they're importing an **entire** directory *src/components/my-component-name* (not the best naming for a guide which led me here..). – user1234SI. Feb 28 '20 at 21:24

4 Answers4

11

The index.js file is good to use when you have a lot of components you need to export from a given folder and you would like to destructure in the files you're importing them into. You don't have to follow this at all, but is still best practice to do it this way; it can be easier when exporting a large amount of files such as from a reducer in Redux or a utility folder with a large amount of smaller components like a <Button> or <Input>, and it is easier to read for other users if everything coalesces into a single index file rather than several different files.

utilityFile/index.js

export {default as Input} from './Input';
export {default as Button} from './Button';
export {default as TextField} from './TextField';

form.js

import {Input, Button, TextField} from './UtilityFile

index.js has special properties that if you import from a file, javascript will look for the index.js if nothing else is specified. Either way works but for larger scale applications using the index.js is preferred.

Khaladin
  • 418
  • 5
  • 11
  • Shouldn't the `import` line in that `form.js` file, read `./index` instead of `'./UtilityFile`? – carloswm85 Dec 03 '21 at 12:55
  • 1
    That's the cool part is node will look for the index.js file in a directory if no file is specified. You're question made me realize I could make my answer a little more clear on that front and I've updated it as such. – Khaladin Dec 07 '21 at 14:16
  • 1
    I read somewhere that `import {A,B} from 'x'` affects tree-shaking and that multiple default imports are better, like `import A from 'x'; import B from 'x';`. Is this true? – Kernel James Jan 18 '22 at 03:05
8

The source you cite is about create-react-app, but the author puts their own opinions on top and presents them as if they're established fact.

If you actually look at the create-react-app documentation (and that's always a good idea: start at the source, then move on to tutorials if the official docs don't cover what you need to know) such as https://create-react-app.dev/docs/importing-a-component#buttonjs, you see them showing exactly what your article says not to do: it's importing a <Button> component from a file called button.js.

By all means, use an index.js if you want implicit imports (there are situations in which it is an excellent idea to do so), but create-react-app doesn't care, it does not "recommend to have an index.js inside that directory", and this article is simply being misleading. There are reasons for adding an index.js, and they are wholly unrelated to create-react-app, React in general, or even the practice of writing JS in class form.

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
6

That's definitely a strategy you can take to structure your components. If you want to is up to you. index.js is treated by webpack differently, so you can just import MyPage from './components/MyPage' and leave the index.js away. A common way to use this practice is to just import and then export the component again from index.js:

MyPage.js

const MyPage = () => <div>Hello world</div>;
export default MyPage;

index.js

import MyPage from './MyPage.js';
export default MyPage;
Damien Flury
  • 769
  • 10
  • 23
2

Some sources say that it's not that you have to, but rather you should avoid adding index.js files. This blog post mentions these reasons to avoid these files:

  1. Circular dependencies.
  2. Unintended imports when using dynamic imports.
  3. Because the creator of Nodejs says it is a mistake. (in this talk)

Another blog post mentions also:

  1. They add noise in the file structure.
  2. They make developers that are not used to this pattern lost.
  3. (again) They lead to circular dependencies.
  4. They can lead to compilation errors.
  5. They prevent Webpack from splitting chunks correctly.

For me, main reason is that these files add unnecessary complexity and actually don't add that much convenience.

On Reddit you can find a short discussion about this issue:

But at the same time if you take advantage of this you will wind up with a whole lot of files with the same name. If you use an editor that let's you open files by name hundreds of index.js files will make that feature slower, and when you're debugging in the browser all you'll see in the stack, at least until you hover over it, is index.js.

And another thread from Reddit where we can find people complaining about the mess that adding these index.js files add:

I personally avoid index files and default imports because it does not help write the code in any possible way. Even nodejs creator regrets adding it to nodejs.

and a quote from user thinkmatt:

I've done both, definitely recommend NOT using index.js/ts files as your normal pattern. It's harder to ctrl+click to get to the function you want, it can also be abused where one index imports another index, etc. on front-end builds, it also prevents tree-shaking. There could be reasons to use it, but I would make it the exception not the rule.

Michał J. Gąsior
  • 1,457
  • 3
  • 21
  • 39