Our React projects' best practices
This is meant to be a guide to help new developers understand the React style and best practices we adopt here at Idealink
To install the package and its dependencies:
$ npm install --save-dev bootstrap@4.6
we highly recommend you to make a commit after each installation
All components (presentation, containers or pages) should always be
named using the CamelCase
naming convention. and the files should follow the camel-case.jsx
naming convention.
Components based on their type should be stored in different directories. the base hierarchy is as follows:
public/
└──
...
└── index.html
src/
└── assets/
├── images/
├── icons/
├── fonts/
└── styles/
├── css/
└── sass/
├── components/
├── common/
└── .../
├── pages/
├── utilities/
├── views/
├── app.jsx
└── index.jsx
- Styles should always be defined in a separate CSS file, don't put all the css codes all together. (if using sass, we expect to have one single source of styles called
styles.scss
and inside that we only import all the other scss files) - Any other asset that we might have like videos and similar files, should go to the /assets folder.
- The components like Header, Footer, Sidebar will go to the common folder of our components directory.
- All the components, that are created for only one single page, will be in a folder with the page name inside the /components directory.
- Each page should be inside the /pages directory with the same name as it's route. (also remember that the component must be
CamelCase
and it's file name is likecamel-case.jsx
) - the format of our files are always
.jsx
for react projects and we don't use the.js
format - We put the helper methods, const data (like a very long list) and things like that inside the /utilities directory
- to keep our code clean, we create very small views for some parts and put them inside the /views directory
Properties from an object that are being used in the same place should be destructed
We use Prettier - Code formatter
VSCode Extension, with the following configurations:
{
"tabWidth": 4,
"useTabs": false,
"semi": false,
"printWidth": 100
}
create a .prettierrc
file, in the root directory of our project, with the above content, after each code change, we restyle the code using ALT + SHIFT + F
on windows and COMAND ON MAC
on macOS
Bad
const onlyNumbersRegex = /^\d+$/;
const validateNumber = (message) => (value) =>
!onlyNumbersRegex.test(value) && message;
validateNumber("error message")(1);
Good
const onlyNumbersRegex = /^\d+$/;
const getNumberValidation = (message) => (value) =>
!onlyNumbersRegex.test(value) && message;
const isNumber = getNumberValidation("error message");
isNumber(1);
Bad
setTimeout(doSomething, 86400000);
Good
const DAY_IN_MILLISECONDS = 86400000;
setTimeout(doSomething, DAY_IN_MILLISECONDS);
- As stated previously, folders and directories must follow the
camel
naming and we appreciate simpe and single word names for our folders and directories. - We use the
.jsx
format all the time and not the.js
format - We use
CamelCase
for the component names and thecamel-case.jsx
for the file names - We use CSS modules everywhere. CSS modules are great because they provide scope to CSS and allow us to create compartmentalized styles that don't leak to global scope.
- use
.dash-case
for css classes all the time.
Why? Mixins introduce implicit dependencies, cause name clashes, and cause snowballing complexity. Most use cases for mixins can be accomplished in better ways via components, higher-order components, or utility modules.
Using ID and tag name at the selector's root makes the rule to be applied globally. we don't want that.
BAD | |
---|---|
import style from "./style.css";
const Item = ({ title, thumbnail }) => (
<div className={style.container}>
<img src={thumbnail} alt={title} />
</div>
);
export default Item; |
img {
background-color: #cccccc;
} |
GOOD | |
import style from "./style.css";
const Item = ({ title, thumbnail }) => (
<div className={style.container}>
<img src={thumbnail} alt={title} />
</div>
);
export default Item; |
.container > img {
background-color: #cccccc;
} |
All components are self-contained and their final size should never suffer margin leakage! This allows the components to be much more reusable!
BAD | GOOD |
---|---|
|
|
When building lists or grids:
- Build list/grid items as separate components
- Use the the list/grid container to space children
- To space them horizontally, use
margin-left
- To space them vertically, use
margin-top
- Select the
first-child
to reset margins
GOOD | |
---|---|
import style from "./style.css";
const Reviews = ({ items }) => (
<div className={style.container}>
{items.map((item) => (
<img src={item.image} alt={item.title} />
))}
</div>
);
export default Reviews; |
.container > img {
margin-left: 10px;
}
.container > img:first-child {
margin-left: unset;
} |
We encourage the "variabilification". Always define variables to increase reuse and make styles more consistent. The CSS4 specification defines a way to declare native variables. We adopted them as the standard.
To define a variable accessible globally:
GOOD | |
---|---|
:root {
--color-green-1: #6ccfae;
--color-green-2: #6b66b5;
--color-green-3: #aac257;
--color-green-4: #68b5c1;
} |
.container {
background-color: linear-gradient(
0deg,
var(--color-green-1),
var(--color-green-2)
);
} |