React Guidelines
A common way to sort the imports in the file is by their source:
external
, absolute
, relative
separated by an empty line. Each of those groups can be sorted by line length, but that's not super important.import React, { useState } from 'react'
import { useTranslation } from 'next-i18next'
import Nav from 'components/layout/Nav'
import Layout from 'components/layout/Layout'
import SimpleForm from './SimpleForm'
import styles from './advanced.module.scss'
Use PascalCase for React components and camelCase for their instances
Pascal cased file names
src/components/GenericForm.tsx
export default function GenericForm() {}
Filename and default component of the file should have the same name.
Camel cased file names
src/utils/hooks/useUser.ts
Lowercase kebab cased folders
src/components/common/password-reset/ResetForm.tsx
Lowercase kebab cased files located in
src/pages/sample-page.tsx
which correspond to /sample-page
url.The common convention is that the main type of the component's props is called after the component itself with suffix
-Props
. Prop types of AdvancedForm
becomes AdvancedFormProps
.type AdvancedFormProps = React.PropsWithChildren({
title?: string
age?: number
})
export default function AdvancedForm({ title = 'Nice', children, age }: AdvancedFormProps) {
return (
<div title={title} data-age={age}>
{children}
</div>
)
}
- Nice IDE support and readability
RegisterPage.tsx
export default function RegisterPage() {
return <div>page</div>
}
- Named functionAllows attaching static props to the function⛅function RegisterPage() {return <div>page</div>}Register.getInitialProps = async (ctx) => {return { stars: 128 }}export default RegisterPage
- Const arrow functionNice for locally defined components🌞const RegisterForm = () => <form>page</form>export default function RegisterPage() {return <RegisterForm />}Okay for default exports, but not preferred⛅const RegisterPage = () => <form>page</form>export default RegisterPage
- Unnamed arrow function⛈Discouragedexport default () => <div>page</div>
- Class components⛈Discouraged as hooks cannot be used inside the class componentsclass Page extends React.Component {render() {return <div>page</div>}}
There are three common ways to style a component:
Single component that inherits all sizing props from MUI https://material-ui.com/system/basics/#all-inclusive
Nice for quick layouts that should follow the theme
🌞
<Box component="nav" px={5} mt={2}>
<a>{t('nav.forgottenPassword')}</p>
</Box>
Not the best for custom scenarios with more than _six props passed to it. Use
⛅
hooks
instead Not nice when the children have clear nesting structure of more than _three levels. Use
⛅
hooks
or scss
instead<Box component="nav" px={5} pb={12} mt={2} mb={4} lineHeight={2} letterSpacing={none} fontSize={20}>
<Box component="span" px={5} pb={12} mt={2} mb={4} lineHeight={2} letterSpacing={none} fontSize={17}>
<a>{t('nav.forgottenPassword')}</p>
</Box>
<Box component="span" px={5} pb={12} mt={2} mb={4} lineHeight={2} letterSpacing={none} fontSize={13}>
<a>{t('nav.forgottenPassword')}</p>
</Box>
</Box>
Nice for very specific styling that leverages
🌞
theme
methods and propsconst useStyles = makeStyles((theme) =>
createStyles({
pageTitle: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: theme.spacing(4),
margin: theme.spacing(5, 3, 4),
color: theme.palette.secondary.main,
backgroundColor: theme.palette.primary.main,
'&:hover': {
color: theme.palette.secondary.dark,
},
},
// ...
}),
)
export default function SomeBox() {
const classes = useStyles()
return (
<Box className={classes.pageTitle}>
<p>{t('nav.forgottenPassword')}</p>
</Box>
)
}
Too verbose for simple use cases, if it contains less than 2 css rules. Use
⛅
Box
instead Not the best when dealing with styling of deep nested structures within the same component. Use
⛅
scss
insteadNext.js supports SCSS out of the box. Read more at https://nextjs.org/docs/basic-features/built-in-css-support#sass-support
File convention is based on a suffix
.module.scss
(ex. about.module.scss
) Nice when dealing with complex nested structures that are scoped in a single component. When dealing with sub-components we're not sure if some of the rules will be left unused.
🌞
@import 'styles/variables';
.page {
color: $text-color;
.nav {
background-color: $nav-color;
a {
text-decoration: none;
text-transform: uppercase;
}
}
}
import styles from './about.module.scss'
<Box className={styles.page}>
<p>{t('nav.forgottenPassword')}</p>
</Box>
Too verbose for simple use cases, if it contains less than 2 css rules in a dedicated file. Use
⛅
Box
instead@import 'styles/variables';
a {
text-decoration: none;
}
Cannot use theme support or theme variables Use
⛈
hook
insteadLast modified 2yr ago