Best practices for naming hooks & props in React

Best practices for naming hooks & props in React
Photo by Ferenc Almasi / Unsplash

As a developer, I think two of the most challenging things in software are (a) naming things and (b) figuring out best practices. Both of these things have many ways of accomplishing the same goal, so it's hard to know which way is recommended.

That's why I decided to make this cheat-sheet. It's a set of best practices for naming things in React. Double whammy!

✌️
Note: Does your application already have patterns you enjoy? Great! That's the end goal of this article! If you're not satisfied, however, read on.

πŸš€ How to name anything in React

Components deal with two types of data: props and state. Props get passed into a component from the function parameters and state gets created within the component's runtime.

Both props and state can contain two types of data. They can contain events and values. An easy way to distinguish between these two is that events = functions and values = variables. Take this component for example:

function Book({ title, description, author, onOpen, onClose }) { ... }

Can you identify which props are values and which are events?

title, description, and author are values.

onOpen, and onClose are events.

πŸš€
Pro tip: values always flow down the React DOM tree, and events always bubble up the tree.

Best practices for naming "data"

Now that you understand the different between data and events, let's talk about naming conventions.

Here's the general advice:

Datatype Naming best practices Examples βœ…
boolean Should include a prefix like is, has etc isVisible hasWatermark canBeProtected
string n/a title, description
number n/a age, contentSize
array Should be plural books items activeLocations

Best practices for naming "events"

Events have more specific best practices for their naming conventions. That's because you want them to be differentiated from data. Here's the 4 golden rules when naming events:

1. Use a prefix to indicate action

Here's an example search component:

function searchbar({ search }) { ... }

Now answer this question: Is this search prop an event or is it data?

If it was an event, it would be called like search('search term') to get a result. If it is data, it would be the search term itself (ex. console.log(search) // 'search term'). I'd argue, because of how we named this parameter, it's not clear whether it's an event or data.

Therefore, you should always use a prefix for events. Example: onSearch, handleSearch, triggerSearch, executeSearch etc.

✌️
Note: This rule can be broken. Sometimes it's more intuitive to simply call the prop search. It takes a judgement call sometimes.

2. Follow React's patterns

HTML has good practices built in. Try to follow them when you can. For example, HTML has events for things such as onclick, onchange, onselect , etc. React renames these to onClick, onChange, onSelect.

Try to follow these as-well. If you want an event to trigger when your component is clicked, don't name it triggerClickEvent or onClicked or onSelected. Just name it either onClick to match react, or if it needs more specifics you can name add a specifier like onItemClick, onBookClick, onProfileClick.

3. Use present tense

Notice how none of HTML/react's event naming is past-tense? That's the correct way to do things. The event is happening in the present, so it should be named like that.

❌ onItemSelected => βœ… onItemSelect

❌ onInputChanged => βœ… onInputChange

❌ onResponseTriggered => βœ… onResponseTrigger

4. Use PascalCase

This is already common in the JavaScript ecosystem, but I thought I'd mention it anyways.

❌ oninputchange => βœ… onInputChange


πŸ”₯Bonus πŸ”₯: Naming custom hooks

Here's how to properly name the custom hook, and how to format the response data.

Naming the custom hook

Once again, here's the general rules:

  1. Start with use
  2. Use present tense
  3. Use pascalCase

βœ… useQueryLookup

βœ… useColorPicker

Naming the return value of a custom hook

Generally hooks can either return data as a single value, an array, or an object. Here's when to use all three:

Single value format

πŸ”₯ const user = useAuth()

A single value should be used when the user is only ever going to read 1 piece of data out of the hook. Typically, this is used for hooks that get their data initially from a useEffect(() => { ... }, []) call. Or hooks where the data is passed in through a context provider.

Array value format

πŸ”₯ const [books, setBooks] = useLibrary();

Lots of react's default hooks use this array response format. This is great for hooks where the response is essentially in [data, event] format. If you need more events consider using object format.

Object value format

πŸ”₯ const { isOpen, onToggle, onOpen, onClose } = useModal();

Lots of custom hooks use the object format. It lets you have a larger API surface and then the consumer of the hook doesn't need to bring in every field if they don't want to.


πŸ”₯Bonus (round 2) πŸ”₯: Naming Form Components

Form components get a specific mention because they're another area where people commonly make mistakes. Again, this is open to interpretation so if your app has a different design pattern, that's okay! This is simply the naming convention I've seen work best, so it's what I recommend.

Firstly, what's a form component? It's the kind of component that would be used in a form in your app. Here's some great examples from popular UI libraries:

Material UI – <Select />

<Select
    id="demo-simple-select"
    label="Age"
    value={age}
    onChange={handleChange}
  >
    ...
  </Select>

Chakra UI – <Input />

<Input value={value} onChange={handleChange)} />

Ant UI – <Switch />

<Switch checked={isChecked} onChange={onChange} />

As you can see, they all have slightly different API's, but they do have one thing in common:

They follow the naming convention of the component they're emulating.

That's my tip for those creating form components. If a component is going to emulate a text input component, make the controlling props be onChange and value. If it's going to emulate a checkbox (ex. anything that is true/false and can be flipped), give it a checked and onChange prop.

Want the full list? Click here for a list of the built-in HTML form components. Try to emulate their API features if you make a similar component as then it will be intuitive for your component consumers.