Logo

dev-resources.site

for different kinds of informations.

Avoiding Common useState() Mistakes in React

Published at
7/1/2024
Categories
react
usestate
dev
javascript
Author
harsh8088
Categories
4 categories in total
react
open
usestate
open
dev
open
javascript
open
Author
9 person written this
harsh8088
open
Avoiding Common useState() Mistakes in React

React's useState hook is a powerful tool for managing component state, but even the most seasoned developers can fall prey to common pitfalls.

Here, we'll explore these mistakes and equip you with the knowledge to craft robust and performant React applications.

1. Mutating State Directly - A Cardinal Sin

React relies on immutability for state updates. This means you should never directly modify the state object returned by useState. Instead, use the setter function provided to create a new state object.

Avoid This ❌

const [count, setCount] = useState(0);

const handleClick = () => {
  count++; // Wrong! This mutates state directly
}
Enter fullscreen mode Exit fullscreen mode

Do This ✅

const handleClick = () => {
  setCount(count + 1); // Create a new state object with updated value
}
Enter fullscreen mode Exit fullscreen mode

2. Forgetting Prior State - Keeping Track of Changes

When updating state, it's crucial to consider the previous state value. React updates occur asynchronously, so directly referencing the current state within the update function might lead to unexpected behavior.

Avoid This ❌

const [todos, setTodos] = useState([]);

const handleAddTodo = (text) => {
  // This might miss newly added todos if called rapidly
  setTodos([...todos, text]); 
}
Enter fullscreen mode Exit fullscreen mode

Do This ✅

const handleAddTodo = (text) => {
  setTodos((prevTodos) => [...prevTodos, text]); // Use the previous state
}
Enter fullscreen mode Exit fullscreen mode

3. Overusing State for Derived Values - When Less is More

useState is ideal for managing simple state, but for complex derived values, consider alternatives like useMemo or custom memoization functions. Overusing state for derived values can lead to unnecessary re-renders and performance issues.

Avoid This ❌

const [todos, setTodos] = useState([]);

const completedTodos = todos.filter((todo) => todo.completed); // Derived value

const renderTodos = () => {
  return (
    <ul>
      {completedTodos.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
};
Enter fullscreen mode Exit fullscreen mode

If a new todo is added (setTodos([...todos, newTodo])), even if it's not completed, both todos and completedTodos will be updated, triggering a re-render of the renderTodos function, even though only the incomplete list needs to be updated.

This unnecessary re-render can be avoided by using techniques like useMemo.

Do This ✅

import { useMemo } from 'react';

const [todos, setTodos] = useState([]);

const completedTodos = useMemo(() => todos.filter((todo) => todo.completed), [todos]); // Memoize based on todos

const renderTodos = () => {
  return (
    <ul>
      {completedTodos.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
};
Enter fullscreen mode Exit fullscreen mode

useMemo ensures completedTodos is only recalculated when the todos array actually changes (based on the dependency array [todos]).

4. Neglecting Optional Chaining - Avoiding Nullish Errors

When dealing with potential null or undefined values within your state object, leverage optional chaining (?.) to prevent errors. This ensures the graceful handling of missing data.

Avoid This ❌


const user = { name: "John" };
const [currentUser, setCurrentUser] = useState(user);

const displayUserName = () => {
  return currentUser.name; // Might throw an error if currentUser is null
}
Enter fullscreen mode Exit fullscreen mode

Do This ✅

const displayUserName = () => {
  return currentUser?.name; // Safe access using optional chaining
}
Enter fullscreen mode Exit fullscreen mode

5. Managing Multiple Inputs - A Formidable Challenge

Handling forms with multiple input fields can get tricky. Consider using an object or an array within your state to manage individual field values. This allows for easier updates and avoids creating separate state variables for each field.

Avoid This ❌

const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [message, setMessage] = useState('');

const handleChange = (event) => {
  if (event.target.name === 'name') {
    setName(event.target.value);
  } else if (event.target.name === 'email') {
    setEmail(event.target.value);
  } else if (event.target.name === 'message') {
    setMessage(setMessage);
  }
};
Enter fullscreen mode Exit fullscreen mode
  • Code Repetition: Updating each field requires separate logic within the handleChange function, making the code repetitive and error-prone.
  • State Management Complexity: As the number of fields increases, managing numerous state variables and their corresponding setters becomes cumbersome.

Do This ✅

const MyForm = () => {
  const [formData, setFormData] = useState({ name: '', email: '', message: '' });

  const handleChange = (event) => {
    setFormData({ ...formData, [event.target.name]: event.target.value });
  };

  return (
    <form onSubmit={(e) => e.preventDefault()}>
      <label htmlFor="name">Name:</label>
      <input type="text" id="name" name="name" value={formData.name} onChange={handleChange} />
      <label htmlFor="email">Email:</label>
      <input type="email" id="email" name="email" value={formData.email} onChange={handleChange} />
      <label htmlFor="message">Message:</label>
      <textarea id="message" name="message" value={formData.message} onChange={handleChange} />
      <button type="submit">Submit</button>
    </form>
  );
};

Enter fullscreen mode Exit fullscreen mode
  • Concise State Management: All form data is stored in a single place, simplifying state management and updates.
  • Cleaner Update Logic: The handleChange function becomes more concise, using the spread operator (...formData) to update a specific field within the state object.

Remember: When dealing with complex forms with nested structures or conditional logic, consider using libraries like Formik or React Hook Form to streamline form validation and state management.

Bonus Tip: When in Doubt, Use useReducer

For complex state management scenarios with intricate update logic, explore useReducer. It provides a more predictable way to handle state updates, especially when dealing with nested state structures.

By following these guidelines and adopting best practices, you'll write cleaner, more maintainable React components that effectively leverage the power of useState. Remember, a well-managed state is the heart of a responsive and performant React application.

Want to stay up-to-date on the latest Tips and Tricks? Like this post and follow us for more content like this!

Happy Coding!!!

dev Article's
30 articles in total
Favicon
Latest Trends in AI in 2025
Favicon
Making Python CLIs More Maintainable: A Journey with Dynamic Command Loading
Favicon
Latest Trends in AI in 2026
Favicon
Meta-Arguments and Provider in Terraform Day 10
Favicon
Lazyvim version 14.x in WSL
Favicon
How to Print in GoLang
Favicon
Hello Dev.to Mates!
Favicon
What's new in Flutter 3.27
Favicon
Amazon S3 Security Essentials: Protect Your Data with These Key Practices
Favicon
Hacktoberfest 2024: A Celebration of Open Source and Community
Favicon
Tech and Tools I use
Favicon
✋🏻 Stop using VS Code Use This — Cursor: The AI Code Editor
Favicon
Djanblog
Favicon
Judging the first DEV Web Game Challenge
Favicon
5 Key Tips for First-Time Software Outsourcing
Favicon
Tips and Tricks for Docker Compose: Leveraging the override Feature
Favicon
Flutter SwitchListTile and ListTile
Favicon
Which flutter features makes you to become a flutter developer?
Favicon
Flutter provides mainly 2 widgets Stateless and StatefulWidget
Favicon
Hello I'am from Brazil and my country recently blocked access to X (Twitter). Lets talk about it
Favicon
Back-End Development: Definition, Stats, & Trends To Follow In 2024
Favicon
Topographical surveyor in Coimbatore
Favicon
How do I close my DEV account
Favicon
Why firebase instead of other databases?
Favicon
Can anybody tell me which popular tech company has best UI LoginScreen?
Favicon
Another great neovim smooth scroll plugin
Favicon
Meme Monday
Favicon
Avoiding Common useState() Mistakes in React
Favicon
Frontend Challenge CSS Beach
Favicon
Ferramentas que não podem faltar no setup de um(a) dev

Featured ones: