Naming things
Consistent naming conventions for variables and functions improve code readability, maintainability, and collaboration. Standardised names can act as self-documenting code, reducing the need for additional comments, and well-named elements help facilitate searching and navigating the codebase.
Also, having rules just means less time wasted chatting about what to call something.
Here are some of the rules I’ve picked up for naming things.
Prefix all booleans with is or has
This indicates the variable type and purpose at a glance, and sets them apart from general data variables.
const bigNumber = number > 999
const App = () => <Component invalid selected featureOn />const isBigNumber = number > 999
const App = () => <Component isInvalid isSelected hasFeature />Prefix all functions that return a boolean with check
This clearly communicates that the function’s purpose is to validate or verify some condition, and
helps to quickly denote that the function will return true or false.
const active = (context) => context.active === 'yes'
const isFull = (context) => context.thing > 0
// Variable must have an awkward name to not shadow the function name.
const isItFull = isFull(foo)const checkActive = (context) => context.active === 'yes'
const checkFull = (context) => context.thing > 0
// Variable can be named complimentary with the function.
const isFull = checkFull(foo)Prefix all callbacks with on, suffixed with the event name
This clearly indicates the function’s purpose to handle a specific event, aligning with common event-driven patterns and making the code more intuitive.
<Component
handleChange={() => {}}
clicked={() => {}}
prevClicked={() => {}}
fetchData={() => {}}
/><Component
onChange={() => {}}
onClick={() => {}}
onPrevClick={() => {}}
onDataFetchSuccess={() => {}}
/>Prefix functions passed to callbacks with handle, suffixed by the event name
This makes it clear that this function is used by a callback, and closely links the two.
const Component = ({ number, onClick }) => {
const addNumber = () => {
onClick(number + 1)
}
return <SubComponent onClick={addNumber}>
}const Component = ({ number, onClick }) => {
const handleClick = () => {
onClick(number + 1)
}
return <SubComponent onClick={handleClick}>
}Prefix setup-only props with default
When a prop is used for setting-up (on mount) only, and then subsequently cannot be controlled by
changing said prop, this is known as a “default” prop. This follows the React pattern of controlled
vs uncontrolled components. e.g. an input can be given a value or a defaultValue, respectively.
<Component open startingValue="foo" isSelected /><Component defaultOpen defaultValue="foo" defaultSelected />Use lower-kebab-case for file and folder names
This helps with readability and quickly scanning file trees.
card header.tsx
pageFooter.tsx
ResultsPerPage.tsx
sort_by_role.tsxcard-header.tsx
page-footer.tsx
results-per-page.tsx
sort-by-role.tsxSuffix test file names with .test
Whilst .spec is also common, using an arbitrary choice is better for consistency, and a file that
contains tests is probably best named appropriately.
test-page-footer.tsx
results-per-page.spec.tsx
sort-by-role.tests.tspage-footer.test.tsx
results-per-page.test.tsx
sort-by-role.test.tsNest components’ and functions’ files in a folder of the same name
This helps with co-locating other files that are locally important to the main file, like tests, supporting utilities, and sub-components. Do not use barrel (index) files as they are hard to navigate, and can cause performance issues with tooling.
components/
page-footer.tsx
results-per-page/
index.tsx
results-per-page.tsx
utilities/
counter.tscomponents/
page-footer/
page-footer.tsx
results-per-page/
results-per-page.tsx
utilities/
count-items/
count-items.tsPrefer named exports
Where possible, use named exports over default exports. They generally provide better support for autocomplete and refactoring, making it easier to maintain and document your code. It’s also perfectly okay to use a file for multiple exports.
const doesThing = () => null
export default doesThingexport const doesThing = () => null