Back to Blog
Lesson 43 of the React Fundamentals: Build Modern UIs from Scratch course
ReactJune 25, 20263 min read

Building a Favorites List: Managing State Arrays in React

Learn to manage an array of IDs in React state to build a robust favorites feature. We cover adding, removing, and updating your UI based on user choices.

Reactstatearraysuser featurescomponentsjavascriptfrontend

Previously in this course, we explored working with LocalStorage to ensure your user's data survives a page refresh. In this lesson, we build on that foundation by implementing a "Favorites" list, focusing on how to manage an array of unique identifiers in your component state to drive interactive user features.

Managing State Arrays from First Principles

In React, state is the single source of truth. When we want to track which movies a user has "favorited," we don't store that information inside the movie objects themselves. Instead, we maintain an array of unique IDs in a parent component's state.

This approach—keeping a list of IDs—is efficient and predictable. If we stored the entire movie object in the array, we would risk data inconsistencies if the original movie list updated. By storing just IDs, we keep our state "normalized," making it easy to toggle items on and off.

Implementing Add and Remove Logic

To manage this list, we need two primary operations: adding an ID (if it's not present) and removing an ID (if it already exists). Because we are working with arrays in state, we must remember the golden rule of React: never mutate the existing array. We always create a new copy.

Here is how you implement this logic in your MovieCard or parent container:

JAVASCRIPT
import { useState } from CE9178">'react';

function MovieBrowser() {
  const [favorites, setFavorites] = useState([]);

  const toggleFavorite = (movieId) => {
    setFavorites((prevFavorites) => {
      // Check if the movie is already favorited
      const isFavorited = prevFavorites.includes(movieId);

      if (isFavorited) {
        // Remove it using filter
        return prevFavorites.filter((id) => id !== movieId);
      } else {
        // Add it using the spread operator
        return [...prevFavorites, movieId];
      }
    });
  };

  return (
    // Render your list and pass toggleFavorite as a prop
  );
}

Updating the UI Based on Favorites

Once you have your favorites array and your toggleFavorite function, the UI needs to react. You’ll want to change the appearance of the "heart" icon or "Favorite" button based on whether the specific movie's ID exists in the favorites array.

This is a perfect use case for conditional rendering. Inside your MovieCard component, you can determine the button state like this:

JAVASCRIPT
function MovieCard({ movie, isFavorited, onToggle }) {
  return (
    <div className="movie-card">
      <h3>{movie.title}</h3>
      <button onClick={() => onToggle(movie.id)}>
        {isFavorited ? CE9178">'❤️ Remove from Favorites' : CE9178">'🤍 Add to Favorites'}
      </button>
    </div>
  );
}

By passing isFavorited (a boolean derived from favorites.includes(movie.id)) as a prop, the component remains "dumb" and purely presentational, which is a core tenet of building modular dynamic movie cards.

Hands-on Exercise

  1. Open your project and add a favorites state array to your main movie container.
  2. Create a toggleFavorite function that uses the logic provided above.
  3. Pass both the function and the current state down to your MovieCard component.
  4. Update your MovieCard to display a different button label or style depending on whether its ID is inside the favorites prop.

Common Pitfalls

  • Mutating the state directly: Avoid using .push() or .splice() on the state array. These methods modify the original array, and React won't trigger a re-render because the reference to the array hasn't changed. Always use .filter(), .map(), or the spread operator [...].
  • Forgetting to check the previous state: When toggling, always use the functional update pattern setFavorites(prev => ...) to ensure you are working with the most recent version of the list, especially if clicks happen in rapid succession.
  • Over-complicating the state: Don't store the full movie object in the favorites list. Keep it simple with an array of strings or numbers (IDs). If you need the full movie data, you can look it up in your main data list using the ID.

Recap

We've successfully moved from static lists to interactive ones. By managing an array of IDs, we've created a clean, performant way to track user preferences. You've learned how to use the functional update pattern to toggle state safely and how to derive UI changes from that state. This is exactly how you build robust user features that feel responsive and professional.

Up next: Handling Media in React.

Similar Posts