When you don't need to use useState in React
React's useState
hook is an integral part of functional component-based state management in React. It allows you to add state functionality to functional components, increasing the utility and flexibility of these components. However, while useState
is commonly used in many React applications, there are scenarios where useState
is not necessary and alternative methods can be used instead.
In this article, we will discuss a few scenarios where you can avoid using useState
, and demonstrate these alternatives with code snippets.
Let's start with a basic useState
example and see which options we have.
import React, { useState } from "react";
export default function App() {
const [email, setEmail] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
alert(`Submitting email ${email}`);
};
return (
<div className="App">
<form onSubmit={handleSubmit}>
<label>
Email:
<input
type="email"
name="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</label>
<button type="submit">Submit</button>
</form>
</div>
);
}
Using useRef instead of useState
One such scenario is when you do not need to re-render a component, but only need to maintain a mutable value. In this case you can use the useRef
hook instead of useState
. Let's have a look at an example:
import React, { useRef } from "react";
export default function App() {
const emailInputRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
alert(`Submitting email ${emailInputRef.current.value}`);
};
return (
<div className="App">
<form onSubmit={handleSubmit}>
<label>
Email:
<input type="email" name="email" ref={emailInputRef} />
</label>
<button type="submit">Submit</button>
</form>
</div>
);
}
In this example, the useRef
hook is used to hold a reference to the email input field. This value is then accessed directly when the form submission is handled. No re-rendering is triggered even if the value of the email input field changes.
Using the FormData pattern instead of useState
Another scenario where useState
can be avoided is when dealing with forms. Normally, you could use useState
to track the value of each form control. But there's an alternative: the FormData
pattern, which uses useRef
and the form data.
import React, { useRef } from "react";
export default function App() {
const formRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData(formRef.current);
alert(`Submitting email ${formData.get("email")}`);
};
return (
<div className="App">
<form ref={formRef} onSubmit={handleSubmit}>
<label>
Email:
<input type="email" name="email" />
</label>
<button type="submit">Submit</button>
</form>
</div>
);
}
In this example, we use useRef
to keep track of the entire form. Then, when the form is submitted, we use the browser's native FormData
API to retrieve the data from the form.
Using useSearchParams instead of useState
The useSearchParams
hook from the react-router-dom
library may be a better option than useState
for dealing with the search parameters of a URL. This hook returns getter and setter methods for the search parameters in a React router's URL. See the example below:
import React from "react";
import { useSearchParams } from "react-router-dom";
export default function App() {
const [searchParam, setSearchParam] = useSearchParams();
const handleSubmit = (e) => {
setSearchParam({ search: e.target.search.value });
alert("search: " + e.target.search.value);
e.preventDefault();
};
return (
<div className="App">
<form onSubmit={handleSubmit}>
<label>
search:
<input name="search" value={searchParam.get("search")} />
</label>
<button type="submit">Submit</button>
</form>
</div>
);
}
In this snippet, instead of using useState
to handle the state of the search input, we use the useSearchParams
hook. This hook automatically synchronises with the URL query parameters, keeping the state synchronised with the URL. The advantage of this approach is that when a user shares the link to your application, fields are pre-populated based on that URL.
In summary
While useState
is an incredibly useful hook in React, there are scenarios where other hooks might be a more efficient alternative. Whether it's avoiding unnecessary renders with useRef
, handling form data with the FormData
pattern, or working with URL parameters with useSearchParams
, alternative methods can often provide simpler and more performant solutions. Remember, the best tool for the job depends on the specific requirements and constraints of your problem.
Happy coding!