There is no official file structure for React components. On the official website, they provide some common approaches for group files: https://reactjs.org/docs/faq-structure.html
In this post, I would explain my way of organizing React components. This method is based on the research from popular projects and the decisions I took after discussing with the developers I had the opportunity to work with.
Here is the summary of the file structures:
I use a main /components
folder to group all of our components at the root level of the project, and inside we have an index.ts
in charge of exporting all the components.
/components/index.ts
An example of a components/index.ts
file would be:
export * from './Button';
Component
For each company, we create a folder with the name Capitalized, e.g., Button
, and inside the main index.ts
in charge of exporting the main component and the respective variants if needed.
/components/Button/index.ts
export * from './Button';
/components/Button/Button.tsx
A quick idea of a Button component with Typescript.
import React, { FC, ButtonHTMLAttributes } from "react";
interface ButtonProps {
...
};
export const Button: FC<ButtonProps & ButtonHTMLAttributes<HTMLButtonElement>> = ({children, ...props}) => {
return (<button {...props}>{children}</button>);
}
Tests
I use jest as our testing framework, And we include our testing files related to the component inside the same folder.
- Button.test.tsx For all the related test cases for each component, the test should have the same name as the component, and It should be located in the same folder, making it easy to find.
- __snapshots__ With jest, you can generate snapshots of the components. For more information, refer to the jest documentation: https://jestjs.io/docs/en/snapshot-testing
Sub Components
Sometimes your main component is composed of other components of a sub level. I have two approaches for these cases:
- styles.tsx
If you have the case where to make your main component more readable, you are creating small presentational components. I would recommend you to move all these small components to a
styles.tsx
file inside the main folder of your component, and import them in your main component file. In this way, you will keep the main component logic only.
- /components
If your main component depends on more complex sub-components, and these components will be used only for this main component. I would recommend adding them inside a
/components
folder located inside your main component folder. E.g.: /components/InputDate/InputDate.tsx
(main logic and states)/components/InputDate/components/Input.tsx
(presentational component)/components/InputDate/components/Calendar.tsx
(logic and calendar state)
Utils
Some components may require to manage a context or may have some hooks to control the logic for all these cases where you need to organize your components' logic. I use a /utils
folder located inside the main component folder.
Final Tip
Your could use alias to import your components like this:
import { Button } from "@components";
// or
import { Button } from "@components/Button";
To do this with Typescript, you can use the path alias inside your tsconfig.json
file:
{
...
"paths": {
"@components": ["src/components/index.ts"],
"@components/*": ["src/components/*"],
}
}
For more information, check Typescript docs: https://www.typescriptlang.org/tsconfig#paths
Conclusions
You don't need to follow my folder and files named conventions, but I would recommend keeping all your files related to each component inside the same folder. This will simplify the decisions for you and your team and make it easy to discover dependent components, related tests, and missing tests.