# SaaS template Coding Conventions

> An explanation of the coding conventions used in the boilerplate

*Canonical: https://makerkit.dev/docs/remix-fire/getting-started/coding-conventions*

---

## React.FC vs React.FCC

Since React 18, `React.FC` no longer implies that components can accept a `children` prop. The alternative to that is using the interface `React.FC<React.PropsWithChildren<{}>>`, which is a bit long.

`React.FCC` is a shorthand that includes `children` as a possible property that works similarly to how it used to work. When a component needs `children`, `React.FCC` is preferred since it's faster to type.

## Exporting functions vs constants

We use both conventions in the boilerplate, i.e., exporting functions as components and constants.

My general rule is the following:

- if it's the exported component, use `const` typed with `React.FC` or `React.FCC`
- if it's not exported, use `function` since my personal preference is to define functions below the exported component

NB: sometimes, that may not be the case, and that's not necessarily intentional. The two constructs are essentially the same in most cases.

## Why is useCallback used in most components?

Most functions defined within a render function use `useCallback`. In my experience, this is the better default to avoid re-renders that I can't immediately explain.

Whether you want to adhere to this convention is totally up to you; just be aware of the potential issues.

## Interfaces, Types, and Inline 

I've gone through phases, so you may find some types defined as `type` and others as `interface`. I've since realized that I prefer `interface`, but you will find some instance that uses `type`.

Inline types are typically only defined when the type isn't reused anywhere. For example, when defining a function that accepts parameters as objects.

## Function parameters

I adhere to the principle that if a function accepts multiple parameters of the same type, then use an object. Unfortunately, Typescript can't save us if the types match.

Consider the example below:

```tsx
function makeDiv(width: number, height: number) {}

const height = 10;
const width = 40;

// correct according to TS, not in practice!
const div = makeDiv(height, width);
```

Now we rewrite it using an object:

```tsx
function makeDiv(params: { width: number, height: number}) {}

const height = 10;
const width = 40;

// Okay, now it looks better!
const div = makeDiv({ height, width });
```

## Custom React Hooks

The boilerplate uses Custom React Hooks when:

- fetching/writing using an API function
- fetching/writing using Firestore
- fetching/writing using Storage

It makes the code more understandable and reusable.
