### Prop drilling
**optional**
[link](https://medium.com/javascript-in-plain-english/how-to-avoid-prop-drilling-in-react-using-component-composition-c42adfcdde1b) [link](https://medium.com/javascript-in-plain-english/how-to-avoid-prop-drilling-in-react-using-component-composition-c42adfcdde1b) [link](https://medium.com/@jeromefranco/how-to-avoid-prop-drilling-in-react-7e3a9f3c8674) [link](https://blog.logrocket.com/mitigating-prop-drilling-with-react-and-typescript/)
E l'effetto negativo di dover passare attraverso più componenti una grande quantità di props.
Può essere mitigato creando meno componenti, ed utilizzando la prop children in modo corretto.
Rappresenta un sostanziale costo di manutenzione e in fase di modifica, costringendo il lettore a controllare molte prop, in diversi componenti ed avere molti file aperti.
### Nomenclatura props
Andrebbero rispettate le nomenclature, verbi per le azioni, sostantivi per i dati, prefisso is per i booleani, e prefisso on per i callback.
```typescript
const [isOpen, setIsOpen] = React.useState(false)
<Modale isOpen={isOpen} onClose={() => setIsOpen(false)}/>
```
Se la nomenclatura non è parlante e rispetta la convenzione, il lettore è costretto ad andare a verificare i tipi e gli utilizzi delle props invece che capirne il significato al volo.
### Uso della API Context
Il context è molto costoso a livello di rendering nel momento in cui il valore del provider cambia.
I context vanno usati solo per informazioni che devono essere visibili a livello di tutta l'applicazione.
Non devono assolutamente essere usati quando basta del prop drilling di pochi livelli.
Per ogni context utilizzato aumenta la difficoltà di lettura 3 modifica del codice poichè si è costretti a fare una ricerca globale su dove viene utilizzato e cosa fa. Purtroppo il tooling non aiuta molto.
Per mitigare la probabilità di errore nel non fornire un context provider, è utile specificare esplicitamente il tipo del context con le parentesi angolari e passsare come valore di default (null as any) in modo da vedere subito l'errore nella UI
```typescript
type Persona = { nome: string; cognome: string };
const ResponsabileContext = React.createContext<Persona>(null as any);
```
### Comandi da tastiera
Tutte le comandistiche da tastiera vanno implementate in un file che contiene tutte le interazioni da tastiera (es: `navigazione-tastiera.ts`), quelle che non sono li dentro vanno eventualemente spostate.
Per un insieme coroposo di interazioni da tastiera può essere creato un file apposito.
Gli eventi da tastiera si possono gestire al meglio se globali ed hanno a disposizione tutte le informazioni per le logiche condizionali.
Non gestendoli a livello globale, e nello stessso file si incorre in problemi di leggibilità, manutenzione, accesso alle informazioni, capturing degli eventi.
Per disambiguare i comandi usare KeyboardNavigationContext.
### Git history
La modalità di lavoro su git concordata è branch development.
Il branch principale è develop, i feature branch invece hanno il prefisso feature.
La modalità di operare è, staccare un feature branch da develop, una volta concluso, deve essere merge-ato su develop.
Se emerge la necessità di portare le modifiche di develop in un feature branch ancora in corso, il feature branch va rebase-ato su develop.
Tutte le altre operazioni git nel nostro caso sono nocive nel nostro contesto, complicano i merge su develop, e impossibilitano la lettura della history.
### Programmazione funzionale
Gli utilizzi non necessari di costrutti non funzionali (for, forEach, let, effect, promise) complicano la lettura e la manutenzione del codice poichè costringono il lettore a controllare tutti i punti di modifica ed eseguire mentalmente gli statement di iterazione.
Ridurre al minimo l'uso di: for (usare map), forEach (usare map), let (usare const)
Ridurre al minimo l'uso di effect e promise
I costrutti imperativi possono essere utilizzati per motivi di performance ma vanno ben isolati dal resto del codice (nasconderli dentro uno scope, ovvero una function)
### Astrazioni
Le astrazioni (es: componenti, componenti che ricevono componenti come props, funzioni, funzioni che ricevono o ritornano funzioni, strutture intermedie che vengono successivamente iterate per essere renderizzate) vanno utilizzate il minimo necessario.
[Dan Abramov](https://www.deconstructconf.com/2019/dan-abramov-the-wet-codebase)
[Sebastian Markbage](https://www.youtube.com/watch?v=4anAwXYqLG8)
Tutte le astrazioni introdotte vanno attentamente discusse con gli team members.
Ogni astrazione introduce un grande livello di indirezione, che complica la lettura e la comprensione del codice, e se compaiono casistiche non previste, possono comportare la riscrittura di grandi parti di codice.
### Performance
Le modifiche al codice per migliorare le performance devono essere fatte solo in questi casi:
- liste o viste tabellari
- interazioni che devono avere feedback istantaneo
Si comincia con l'analisi tramite il profiler di react [dev tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi), e si procede con la memoizzazione, delle props con React.memo e dei stati derivati con useMemo
Apportare modifiche per le performance prima di avere una misurazione, o in sezioni che non lo richiedono è un perdita di tempo, e può addirittura provocare l'effetto contrario.
Non apportare modifiche per le performance, e non predisporre i componenti per un rendering performante appena se ne nota la necessità, comporta un debito tecnico che cresce esponenzialmente con le nuove modifiche, fino ad arrivare a rendere impossibile l'efficientamento del rendering.
### Tipizzazione
Va assolutamente evitato l'utlizzo di any, perchè disabilita il typechecking propagandi in tutti i siti di utilizzo, costringendo il lettore del codice a controllare il molteplici punti che forma ha quel dato, inoltre si perde anche la possibilità di autocompletamento.
Gli enum non vanno usati poichè in via di deprecazione, e sono anche difficili da modificare ed utilizzare.
Va usato `type` e non `interface`, poichè le interface hanno il declaration merging.
I DTO devono essere tipizzati, per evitare lunghe sessioni di debugging cercando l'attributo colpevole.
### Stilizzazione
Per gli stili condizionali vanno usate le props [link](https://styled-components.com/docs/basics#passed-props) [link](https://styled-components.com/docs/basics#attaching-additional-props)
Non usare le classi perchè viene meno l'information hiding, l'utilizzatore dello styled component è costretto a leggere l'implementazione ogni volta.
Gli styled component devono avere il prefisso `Styled`.
**optional** Quando stili di due elementi diversi sono direttamente dipendenti (es: flex + flex-grow; grid + grid-row) vanno scritti in linea con
```typescript
<div
css={css`
display: flex;
`}
>
<StyledQualcosa
css={css`
flex-grow: 1;
`}
></StyledQualcosa>
</div>;
const StyledQualcosa = styled.div`
background-color: red;
`;
```
Il resto della suddivisione tra inline e styled components è a discrezione.
### Custom Hooks
Le custom hook vanno create solo se:
- rappresentano un'astrazione ben definita riutilizzabile in più punti
- incapsulano una business logic non realizzabile con funzioni semplice
Non vanno usate invece per:
- spezzare una hook troppo grande
- incapsulare pochi hook senza logica (meglio scrivere inline)
Gli effetti negativi sono:
- lista infinita di parametri
- troppe custom hook, che comportano difficolta di lettura e modifica
### Thinking in React
[link](https://it.reactjs.org/docs/thinking-in-react.html)
Alla base di react ci sono:
- gli stati base (useState)
- gli stati derivati (useMemo, da usare quando lo stato derivato creerebbe una nuova istanza, ad esmpio gli array)
- gli effetti (useEffect, che vanno usati esclisivamente per io)
Non si devono usare assolutamente gli effect per sincronizzare lo stato, perchè aggiunge moltissimi livelli di indirezione, ed è molto facile dimenticarsi di collegare tutti gli effect creando bug difficilemnte risolvibili e anche race conditions.
### Fetching
**in fase di allineamento**
Il ritrovamento di risorse asincrone deve essere fatto con la libreria [SWR](https://swr.vercel.app/).
Per recuperare una risorsa va creata una funzione parlante che al proprio interno utilizza l'api fetch.
Eventuali adattamenti del dto vanno svolti nel metodo asincrono.
```typescript
async function getPersonaById(id: string): Promise<Persona> {
const reponse = await fetch(`${rootRoot}/persona/${id}`);
const data = await response.json();
if (data.error) throw data.error;
return data;
}
function DettaglioPersona() {
const [id, setId] = React.useState<string | null>(null);
const { data } = useSWR(id, getPersonaById);
return null;
}
```
### Nomenclatura di dominio
**da definire**
La nomenclatura di dominio è: entità in italiano, prefissi e suffissi in inglese.
I DTO devono avere i campi in italiano.
Qualora necessario devono essere scritti funzioni adapter che trasformano i DTO in italiano.
Non deve capitare che lo stesso concetto abbia nomi diversi.
### Code locality
Usiamo l'approccio "il codice deve stare il più vicino possibile a dove viene utilizzato", per evitare di creare troppi file di difficile navigazione.
Il criterio per spostare un blocco di codice in un file dedicato è quando viene utilizzato in più file.
Il criterio per dedicare un file apposito ad un componente: il componente è autosufficiente e visualizza una view all'interno di un quadrato
Gli styled components vanno scritti nel file dove vengono utilizati, possono essere spostati in un file apposito solo se utilizzati da altri file.
### Dead code
Il codice non più utilizzato non va assolutamente committato, poichè è pressochè impossibile individuarlo con certezza successivamente.
La fase di stage si presta benissimo a questo controllo (si può usare anche la funzione "trova tutte le referenze" di vscode per essere sicuri)
### Variables
- Use `const` for all of your references; avoid using `var`.
> Why? This ensures that you can’t reassign your references, which can lead to bugs and difficult to comprehend code.
- If you must reassign references, use `let` instead of `var`.
> Why? `let` is block-scoped rather than function-scoped like `var`.
### Naming Conventions
Name a file like React already does:
- Extensions: Use .tsx extension for React components.
- Filename: Use PascalCase for filenames. E.g., App.tsx, SmartSearch.tsx.
- Reference Naming: Use PascalCase for React components and camelCase for their instances.
- Use unique names for files (for better debugging and navigation experience)
```javascript
// bad
import reservationCard from "./ReservationCard";
// good
import ReservationCard from "./ReservationCard";
// bad
const ReservationItem = <ReservationCard />;
// good
const reservationItem = <ReservationCard />;
```
### Props
- Always use camelCase for prop names.
- Omit the value of the prop when it is explicitly true.
- Always include an `alt` prop on `<img>` tags. If the image is presentational, `alt` can be an empty string or the `<img>` must have `role="presentation"`.
- Do not use words like "image", "photo", or "picture" in `<img>` alt props.
> Why? Screenreaders already announce img elements as images, so there is no need to include this information in the alt text.
- Avoid using an array index as key prop, prefer a stable ID.
> Why? Not using a stable ID [is an anti-pattern](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318) because it can negatively impact performance and cause issues with component state.
- Always define explicit defaultProps for all non-required props.
### Parentheses
- Wrap JSX tags in parentheses when they span more than one line.
### Tags
- Always self-close tags that have no children.
- If your component has multi line properties, close its tag on a new line.
### Mixins
- Do not use mixins.
> 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.
### Style
- Avoid creating a styled-component for every single HTML element in page:
- Use in-line css in first instance
- Write a styled-component if the element is repeated inside the component defined in that file
- Abstract the styled-component inside its own file if the element in repeated across the project
- Use only the notation `Muli` or `Roboto` for `font-family` attribute
- Use the numeric notation for `font-weight` attribute (avoid use of bold, bolder etc.)
- Use `rem` as unit of measure for `font-size`. Default font size is 16px rely on this to make the conversions. Use https://nekocalc.com/px-to-rem-converter for convert px -> rem
## Ordering
Top Down ordering approach inside a component
1. smart component (uses hooks)
2. hooks
3. data fetching
4. derived data (extract only if necessary)
5. dumb components (only graphical components with callbacks with few or no logic)
6. styled component