3 Best React Practices for ReactJS Form

Author Profile
Abdul Basit OnLinkedIn

As a naive React developer, I often used to come across the typical issue of all coders, which is too many lines of code!

It used to get so overwhelming – not only for me, but also for the systems I had to code for. Because the more lines of code, the more chances for coding errors and lagging performance of the system.

Over time, I searched around and found some of the best React practices for ReactJS Form without the use of any third-party library.

So, I’m sharing my personally tried-and-tested top 3 react best practices for ReactJS Form with you. Because I want you to do better, which I wasn’t able to do in my beginning days as a React developer.

In case you are in a hurry, here is a glimpse of what are we going to talk about:

  • state Object in ReactJS Form
  • Reusable Components in ReactJS Form
  • React Custom Hooks in ReactJS Form

So without any further ado, let’s dive in!

1. state Object in ReactJS Form

Let’s assume that you have two values to render, then there won't be any issue to use a separate state for each value. Just as illustrated in the following example:

const [quote, setQuote] = useState('')
const [author, setAuthor] = useState('')

But in the case of a form that has multiple values to fill in – let’s say a review form having more than five values – then, it's recommended to use object in useState for a cleaner look of the code. Something like this:

const [formData, setFormData] = useState({
name: '',
email: '',
phone: '',
message: '',
rating: '',
})

On the other hand, we can setState using Javascript computed property and having dynamic keys using name property.

const onChangeInput = (e) => {
const { name, value } = e.target
setFormData({ ...formData, [name]: value })
}

2. Reusable Components in ReactJS Form

The reusable components in React are the pieces of UI that can be used again in multiple places. For example, you can use a Button component in different places in app to display different texts.

Let’s assume that we have to create a form with the input and submit button. Then, my approach will be to have a separate component for both of them – the input and submit button.

If you want to learn more about building a custom input component and a loading spinner button with best practices and scalable architecture, you can refer to these articles:

  1. Custom Input Component
  2. Loading Spinner Button

Here is the snippet of my React code:

import { useState } from 'react'
import Button from '../components/Button'
import Input from '../components/Input'
const LoginForm = () => {
const [user, setUser] = useState({ email: '', password: '' })
const onChangeInput = (e) => {
const { name, value } = e.target
setUser({ ...user, [name]: value })
}
const onSubmitForm = (e) => {
e.preventDefault()
console.log('user', user)
}
const { name, email } = user
return (
<form onSubmit={onSubmitForm}>
<Input
name="email"
value={email}
type="email"
placeholder="Type your email..."
onChange={onChangeInput}
/>
<Input
name="password"
value={password}
type="password"
placeholder="Type your password..."
onChange={onChangeInput}
/>
<Button title="Submit" type="submit" />
</form>
)
}
export default LoginForm

Similarly, we can add label, error, and icon too in our input component.

3. React Custom Hooks in ReactJS Form | useForm Hook

There are two types of React components, stateful and stateless. The one that holds some state or some logic is called the stateful. This means it must have some logic to perform when interacting with the user. While the other has no state at all, which is why it is known as stateless.

So, the React component on which we are going to work on is a stateful component. You’ll extract the logic of the state along with all functions by using the custom hooks. And then, use it at many places within the React app. For instance, we can have custom hooks of the login form for the signup, contact, review, and subscription.

Now, let’s code to make the state of onChangeInput and onSubmit function into a custom reusable hook. I’ll start by creating a hook folder in src and a file named useForm.js inside that folder. But remember, all hooks in React must start with the use keyword.

Here is the snippet of the actual UseForm Hook:

import { useState } from 'react'
const useForm = (formState) => {
const [user, setUser] = useState(formState)
const onChangeInput = (e) => {
const { name, value } = e.target
setUser({ ...user, [name]: value })
}
const onSubmitForm = (e) => {
e.preventDefault()
console.log('user', user)
}
return {
user,
onChangeInput,
onSubmitForm,
}
}
export default useForm

So, we can extend the above useForm Hook by adding errors or any other features that you want them to execute on a certain state that it renders.

After the useForm Hook is customized according to our interaction logic, this is how it’ll look:

import Button from '../components/Button'
import Input from '../components/Input'
import useForm from '../hooks/useForm'
const LoginForm = () => {
const { user, onChangeInput, onSubmitForm } = useForm({
email: '',
password: '',
})
const { email, password } = user
return (
<form onSubmit={onSubmitForm}>
<Input
name="email"
value={email}
type="email"
placeholder="Type your email..."
onChange={onChangeInput}
/>
<Input
name="password"
value={password}
type="password"
placeholder="Type your password..."
onChange={onChangeInput}
/>
<Button title="Submit" type="submit" />
</form>
)
}
export default LoginForm

Doesn’t this look much simpler and cleaner?

Finally, you can use this custom hook useForm in other places of React app too – wherever the form we use.

To Sum Up

These are the top 3 best React practices for any ReactJS form. This highly reduces unexpected behavior or errors of the React components. Plus, you can easily maintain a clean, scalable, well-laid-out syntax and reusable functions within minimum lines of code for future use in your React projects.