## CSS These coding rules are taken from the Airbnb React/JSX Style Guide. ### Use CSS modules With CSS Modules, it’s a guarantee that all the styles for a single component: 1. Live in one place 2. Only apply to that component and nothing else Plus, any component can have a true dependency, like: ```tsx import buttons from "./buttons.css"; import padding from "./padding.css"; element.innerHTML = `
`; ``` **This approach is designed to fix the problem of the** ***global scope*** **in CSS (**[**ref**](https://css-tricks.com/css-modules-part-1-need/)**).** ## Factoring Have a look at the following page(s) : - [The Twelve-Factor App](https://12factor.net/) ## Naming - **Extensions**: Use `.tsx` extension for React components. - **Filename**: Use PascalCase for filenames. E.g., `ReservationCard.jsx`. - **Reference Naming**: Use PascalCase for React components and camelCase for their instances. eslint: `react/jsx-pascal-case` ```tsx // πŸ’© import reservationCard from './ReservationCard'; // πŸ‘ import ReservationCard from './ReservationCard'; // πŸ’© const ReservationItem = ; // πŸ‘ const reservationItem = ; ``` - **Component Naming**: Use the filename as the component name. For example, `ReservationCard.jsx` should have a reference name of `ReservationCard`. However, for root components of a directory, use `index.jsx` as the filename and use the directory name as the component name: ```tsx // πŸ’© import Footer from './Footer/Footer'; // πŸ’© import Footer from './Footer/index'; // πŸ‘ import Footer from './Footer'; ``` - **Higher-order Component Naming**: Use a composite of the higher-order component’s name and the passed-in component’s name as the `displayName` on the generated component. For example, the higher-order component `withFoo()`, when passed a component `Bar` should produce a component with a `displayName` of `withFoo(Bar)`. Why? A component’s `displayName` may be used by developer tools or in error messages, and having a value that clearly expresses this relationship helps people understand what is happening. ```tsx // πŸ’© export default function withFoo(WrappedComponent) { return function WithFoo(props) { return ; } } // πŸ‘ export default function withFoo(WrappedComponent) { function WithFoo(props) { return ; } const wrappedComponentName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; WithFoo.displayName = `withFoo(${wrappedComponentName})`; return WithFoo; } ``` ## Logging Client-Side and Server-Side should logs the message through a function for future adaptability. ## National Language Support (NLS) Every text displayed to the used should be gathered into one file, in order to ease the traduction that we could need in the future. ## React ### Basic Rules - Only include one React component per file. - However, multiple [Stateless, or Pure, Components](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions) are allowed per file. eslint: `react/no-multi-comp`. - Always use TSX syntax. - Do not use `React.createElement` unless you’re initializing the app from a file that is not TSX. - `react/forbid-prop-types` will allow `arrays` and `objects` only if it is explicitly noted what `array` and `object` contains, using `arrayOf`, `objectOf`, or `shape`. ### Class vs `React.createClass` vs stateless - If you have internal state and/or refs, prefer `class extends React.Component` over `React.createClass`. eslint: `react/prefer-es6-class` `react/prefer-stateless-function` ```tsx // πŸ’© const Listing = React.createClass({ // ... render() { return
{this.state.hello}
; } }); // πŸ‘ class Listing extends React.Component { // ... render() { return
{this.state.hello}
; } } ``` And if you don’t have state or refs, prefer normal functions (not arrow functions) over classes: ```tsx // πŸ’© class Listing extends React.Component { render() { return
{this.props.hello}
; } } // πŸ’© (relying on function name inference is discouraged) const Listing = ({ hello }) => (
{hello}
); // πŸ‘ function Listing({ hello }) { return
{hello}
; } ``` ### Mixins - [Do not use mixins](https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html). > 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. ### Share Data with Props To pass data into a component with props, we will try to use as much as possible the [object destructuring synthax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#object_destructuring). ```tsx // πŸ’© function MyComponent({ name }) { return

πŸ”₯ {name}

; } // πŸ‘ function MyComponent(props) { return

πŸ”₯ {props.name}

; } // Both can be used by the same way ``` ### [Antipatterns to avoid](https://www.youtube.com/watch?v=b0IZo2Aho9Y&list=PL0vfts4VzfNgUUEtEjxDVfh4iocVR3qIb&index=15) #### [01:00](https://www.youtube.com/watch?v=b0IZo2Aho9Y&list=PL0vfts4VzfNgUUEtEjxDVfh4iocVR3qIb&index=14&t=60s) Big Components πŸ’© A dirty React component : ![img](https://miro.medium.com/max/1400/1*yMx7iU9sxrxnUOVZSs_rCg.png) πŸ‘ Prefer functional components with React Hooks πŸ‘ DRY πŸ‘ Proper naming & props destructuring πŸ‘ If you use JS add a PropTypes validation layer πŸ‘ Split into small pieces `List.js` : ![img](https://miro.medium.com/max/3400/1*J37slRTcWt7a8AgAGhygQQ.png) `Listen.js` : ![img](https://miro.medium.com/max/2504/1*zkHad6Ktu2nPDU8pFEzL9Q.png) Reference : [Refactoring a Complex React Component](https://levelup.gitconnected.com/refactoring-a-complex-react-component-5-best-practices-to-write-efficient-and-readable-components-b0d06f4f22b4) #### [01:55](https://www.youtube.com/watch?v=b0IZo2Aho9Y&list=PL0vfts4VzfNgUUEtEjxDVfh4iocVR3qIb&index=14&t=115s) Nesting Gotcha πŸ’© *Child using the function defined by the parent => bad performance issue* ```tsx function Parent(){ const[count, setCount] = useState(0); const handleClick = () => setCount(count+1); const Child = () => { return } } return (
) ``` πŸ‘ *pass the function in as a prop* ```tsx const Child = ({onClick}) => { return } function Parent(){ const[count, setCount] = useState(0); const handleClick = () => setCount(count+1); } return (
) ``` #### [02:35](https://www.youtube.com/watch?v=b0IZo2Aho9Y&list=PL0vfts4VzfNgUUEtEjxDVfh4iocVR3qIb&index=14&t=155s) Failure to memoΓ―se If your component renders the same result given the same props, you can wrap it in a call to `React.memo` for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result. `React.memo` only checks for prop changes. ```tsx function MyComponent(props) { /* render using props */ } function areEqual(prevProps, nextProps) { /* return true if passing nextProps to render would return the same result as passing prevProps to render, otherwise return false */ } export default React.memo(MyComponent, areEqual); ``` This method only exists as a [**performance optimization**](https://reactjs.org/docs/optimizing-performance.html)**.** Do not rely on it to β€œprevent” a render, as this can lead to bugs. #### [03:15](https://www.youtube.com/watch?v=b0IZo2Aho9Y&list=PL0vfts4VzfNgUUEtEjxDVfh4iocVR3qIb&index=14&t=195s) Useless Divs πŸ’© *As JSX need to return only one element, I wrap the two elements into a* `div` ```tsx function Frag(){ return (
) } ``` πŸ‘ *As JSX needs to return only one element, I wrap the two elements into a* `` *or a* `` ```tsx function Frag(){ return ( <>
) } ``` #### [03:44](https://www.youtube.com/watch?v=b0IZo2Aho9Y&list=PL0vfts4VzfNgUUEtEjxDVfh4iocVR3qIb&index=14&t=224s) Messy Files React components should be organised by folders, in which one folder contains one React component. These folders should include at least a structure similar to the following one (here example with *Navbar*) : ```tsx Navbar └── index.tsx β”œβ”€β”€ Navbar.module.css β”œβ”€β”€ Navbar.spec.ts └── Navbar.tsx ``` The`index.tsx` helps to import our component like this : - `import Navbar from './Navbar';` πŸ‘ - not like that : `import Navbar from './Navbar/Navbar';` πŸ’© The`index.tsx` includes the following : ``` export { default } from './Navbar'; ``` To help, it has been implemented a folder template that can be used with the [vscode folder template extension](https://github.com/Huuums/vscode-folder-templates). #### [04:40](https://www.youtube.com/watch?v=b0IZo2Aho9Y&list=PL0vfts4VzfNgUUEtEjxDVfh4iocVR3qIb&index=14&t=280s) Big Bundles If a slow initial page load occurs, it may means the app is too big (importing too much stuff), to tackle this trouble we would try to load some module asynchronously. πŸ‘ *Using* `lazy` *loading and* `Suspense`: ```tsx const Button = React.lazy(() => import('./Button')); function Page(){ return ( Loading...
}> ); } ``` However if we had to choose one, we may think about Recoil, for the following reason : - It was built and released by engineers from Facebook's team, the React creator. - It doesn't impose a strict learning curve as Redux and Mobx do. - it doesn't intend to have so much Redux boilerplate in the codebase. ##### How to pass data among react component siblings ? - Redux β†’ no - ContextAPI (`useContext` hook) β†’ parsimoniously, cause it makes you contained component impossible to reuse without having it with the same context (given by the same outside parent component). - Combination of callback and use of props β†’ yes #### [06:30](https://www.youtube.com/watch?v=b0IZo2Aho9Y&list=PL0vfts4VzfNgUUEtEjxDVfh4iocVR3qIb&index=14&t=390s) Prop Plowing Try to use the [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) when you can. Here an example for spread props : ```tsx const data = { id: 7 name: "John", age: 29 } return ( // // πŸ’© // πŸ‘ ) ```