skip to Main Content

I have designed a page in React where all styled colors change, depending on whether the user is signed in or not. I have been successful with the entire page except when it comes to changing the color of the links on hover. As is, when a link is hovered, the entire set of links is changing color, rather than just the one link. Running map() on each item I thought would produce the desired effect on each item but it is not working that way. I can’t see why this code doesn’t work. (All my colors are being applied in-line)

const links = [
  {
    link: 'Category 1',
  },
  {
    link: 'Category 2',
  },
  {
    link: 'Category 3',
  },
];
function App() {
  const [currentUser, setCurentUser] = useState(false);
  const [noUserColors, setNoUserColors] = useState('green');

  const handleNoUserMouseEnter = () => {
    setNoUserColors('blue');
  };

  const handleNoUserMouseLeave = () => {
    setNoUserColors('green');
  };

  return (
    <>
      <ul>
        {links.map((link) => {
          return (
            <li>
              {currentUser || (
                <a
                  style={{ color: noUserColors }}
                  onMouseEnter={handleNoUserMouseEnter}
                  onMouseLeave={handleNoUserMouseLeave}
                >
                  {link.link}
                </a>
              )}
            </li>
          );
        })}
      </ul>
    </>
  );
}``
    

2

Answers


  1. The issue you are encountering is due to the fact that all links share the same state (noUserColors) since you are using the same state variable for all of them. As a result, when the state changes, it affects all links simultaneously.

    To handle the hover effect on each link independently, you need to maintain individual states for each link. You can modify your component to store the hover color state for each link separately.

    Here’s an example of how you might achieve this:

    import React, { useState } from "react";
    
    const links = [
      {
        link: "Category 1",
      },
      {
        link: "Category 2",
      },
      {
        link: "Category 3",
      },
    ];
    
    function App() {
      const [currentUser, setCurrentUser] = useState(false);
    
      // Create an object to store hover colors for each link
      const [hoverColors, setHoverColors] = useState({});
    
      const handleMouseEnter = (index) => {
        setHoverColors((prevColors) => {
          return { ...prevColors, [index]: "blue" };
        });
      };
    
      const handleMouseLeave = (index) => {
        setHoverColors((prevColors) => {
          return { ...prevColors, [index]: "green" };
        });
      };
    
      return (
        <>
          <ul>
            {links.map((link, index) => (
              <li key={index}>
                {currentUser || (
                  <a
                    style={{ color: hoverColors[index] || "green" }}
                    onMouseEnter={() => handleMouseEnter(index)}
                    onMouseLeave={() => handleMouseLeave(index)}
                  >
                    {link.link}
                  </a>
                )}
              </li>
            ))}
          </ul>
        </>
      );
    }
    
    export default App;
    

    In this example, the hoverColors state is an object where each key is the index of a link, and the value is the hover color for that link. This way, each link has its own hover color state, and changing the color of one link won’t affect the others.

    Login or Signup to reply.
  2. Since you have a list of items, each item could have its own state.
    And when you mouse over could update only the item in that particular index.

    So for example could consider initialising everything as green as follows.

    const [linkColors, setLinkColors] = useState(links.map(() => 'green'));
    

    Then on mouse over could update as follows:

    const newColors = [...linkColors]; // get all state values so that we don't override everything.
    newColors[index] = 'blue'; // only update on the index you mouse over.
    setLinkColors(newColors); // set back the state.
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search