community
community copied to clipboard
Clean code Conventions - Atomic Design
Description
- Flow types was installed in the project and applied in a few files, now it's time to apply types in the whole project.
- It's necessary for future developers to have harmony in the code. All our code should be written with the same style following our coding best practices, coding conventions and eslint rules (if applicable).
Code style and conventions proposal:
Directories
- We use atomic design: Not strict with the whole methodology but at least we need to respect atoms and molecules.
- For each component folder we should have a main file for the main component we are exporting with the same name as the component. i.e:
src/atoms/Link/Link.js
- A components folder inside the component folder will contain all necessary sub-components that we need.
- A data folder will contain hooks or functions for query data, it can also contain static data files or anything related to data needed for this component.
- A transformers folder will contain functions that transform or format data.
- A hooks folder will contain any custom react hook we need for this component.
- A types file will contain shared types.
This directory structure can be also used for shared code, for instance, we can have a hooks folder at the root of the project containing custom hooks we use everywhere.
Code conventions
- WET principle: We do not rush on creating abstractions, if the same piece of code is about to be written for the third time then it's time to consider abstracting this code into one shared piece of code.
- Verbose and descriptive: It's better to have large and descriptive code than one-liners, try to avoid multiple files or abstractions just to have files with fewer lines. We are a team and we all need to understand the code as quickly as possible and enjoy the process. This doesn't mean it has to be always like that, sometimes one-line code it's necessary for multiple reasons, just be conscious about it.
- Bussines logic, states, and presentational components: We try as much as possible to encapsulate large business logic or complex state management into hooks, functions, or components that only provides data for children (commonly known as containers) and we keep the other components only to receive props and render the UI. This approach makes it much easier for developers to quickly identify where the business logic, the state management, and the presentational code are and makes it much easier to reuse code. Presentational components are usually stateless, which makes them much easier to reuse if they only receive props and render.
- Function expressions vs const vs let: We prefer
functions expression
for functions andconst
andlet
for anything else. With exceptions of cases where arrow functions wrapped in a const or tagged template literals as functions arguments are mandatory. - Const vs let: Following the principle of React state, we prefer functional code as much as possible, trying to avoid undesired side effects and mutations. Therefore be conscious about the use of let, most of the time it's possible to use const instead.
- Mutation: Mutation is not something bad, just try to be very intentional about what you're mutating and when. By the time you mutate an object, variables and properties may already be pointing at it. Your mutation affects any code “following” those wires later.
- React fragments vs empty tag: We prefer
Fragment
since empty tags don't allow props or keys, therefore it will be inconsistent having places with Fragments and places with empty tags. - JSX render conditions: We prefer ternary operator instead of boolean conditions in order to always render what we want or render null.
i.e:
<Component> {value && <Component2 />} // If condition is false an empty `div` will be rendered, we don't want that. {value ? <Component /> : null} // If condition is false null will be rendered, which is what we want. </Component>
- Types:
- Naming convention:
T
followed by type name. i.e:type TComponentProps
- Location: Place types that are not shared in the file just above where it's being used, this way it's easier to quickly find the type definition. For shared types, create a
types.js
in the parent folder of the files that types are shared with and place all the types you need there.
- Naming convention:
- GraphQL:
- Graphql queries should be at the end of each file in order to make readability easier, first thing a developer want to see usually is the main code exported.
Goals
- [ ] Type the code #1237
- [ ] Refactor code style where is needed and add eslint rules that can help us for fast and better coding experience. #