Why do I have to create index.js file for components?

Viewed 10744

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?

3 Answers

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.

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.

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;
Related