Home > front end >  When making hover function by 'onMouseEnter' and 'onMouseLeave' function, how ca
When making hover function by 'onMouseEnter' and 'onMouseLeave' function, how ca

Time:02-01

You may not understand the title, but I'll explain what the question is.

I'm trying to make some buttons. the button is changed when it's hovered.
The button originally selected does not change when other button is hovered, but changes when other button is selected.
I think you can understand what I mean immediately if you look at the code or codesandbox link below.

Question:
As you can see, I used 'onMouseOver' and 'onMouseLeave' function to implement hover.
But, when the component is first rendered, if one button is clicked, other button should change, but it doesn't change.
I'm sure this is because 'onMouseLeave' function is executed when mouse is entered to button at first.
So, when I click other button, the first one doesn't change because I didn't enter it.
I want it to work properly even if I click another button without passing the first button.
How can I modify it??

code

import { useState } from "react";
import styled from "styled-components";

export default function App() {
  // declare hover state
  const [choonsik, setChoonsik] = useState(true);
  const [ryan, setRyan] = useState(false);
  const [apeech, setApeech] = useState(false);

  // declare click state
  const [isChoonsik, setIsChoonsik] = useState(true);
  const [isRyan, setIsRyan] = useState(false);
  const [isApeech, setIsApeech] = useState(false);

  // make click state true
  const clickChoonsik = () => {
    setIsChoonsik(true);
    setIsRyan(false);
    setIsApeech(false);
  };

  const clickRyan = () => {
    setIsChoonsik(false);
    setIsRyan(true);
    setIsApeech(false);
  };

  const clickApeech = () => {
    setIsChoonsik(false);
    setIsRyan(false);
    setIsApeech(true);
  };

  // make hover state true
  const trueChoonsik = () => {
    setChoonsik(true);
  };

  const trueRyan = () => {
    setRyan(true);
  };

  const trueApeech = () => {
    setApeech(true);
  };

  // make hover state false
  const falseChoonsik = () => {
    setChoonsik(false);
  };

  const falseRyan = () => {
    setRyan(false);
  };

  const falseApeech = () => {
    setApeech(false);
  };

  return (
    <Wrap
      choonsik={choonsik}
      ryan={ryan}
      apeach={apeech}
      isChoonsik={isChoonsik}
      isRyan={isRyan}
      isApeech={isApeech}
    >
      <div className="characterWrap">
        <ul className="characterWrap__list">
          <li className="characterWrap__card">
            <div
              onm ouseEnter={() => {
                trueChoonsik();
              }}
              onm ouseLeave={() => {
                falseChoonsik();
              }}
              onClick={() => {
                clickChoonsik();
              }}
              className={`characterWrap__choonsik ${
                choonsik || isChoonsik ? "active" : ""
              }`}
            >
              <div
                className={`choonsik ${choonsik || isChoonsik ? "active" : ""}`}
              />
              춘식이
            </div>
          </li>
          <li className="characterWrap__card">
            <div
              onm ouseEnter={() => {
                trueRyan();
              }}
              onm ouseLeave={() => {
                falseRyan();
              }}
              onClick={() => {
                clickRyan();
              }}
              className={`characterWrap__ryan ${
                ryan || isRyan ? "active" : ""
              }`}
            >
              <div className={`ryan ${ryan || isRyan ? "active" : ""}`} />
              라이언
            </div>
          </li>
          <li className="characterWrap__card">
            <div
              onm ouseEnter={() => {
                trueApeech();
              }}
              onm ouseLeave={() => {
                falseApeech();
              }}
              onClick={() => {
                clickApeech();
              }}
              className={`characterWrap__apeach ${
                apeech || isApeech ? "active" : ""
              }`}
            >
              <div className={`apeach ${apeech || isApeech ? "active" : ""}`} />
              어피치
            </div>
          </li>
        </ul>
      </div>
    </Wrap>
  );
}

const Wrap = styled.div`
  position: relative;
  width: 1000px;
  top: calc(50vh - 100px);

  .characterWrap {
    padding-bottom: 20px;
    margin: 0 auto;
    width: 100%;
    text-align: center;
  }

  .characterWrap__list {
    display: inline-flex;
    list-style: none;
  }

  .characterWrap__card {
    margin: 0 9px;
    text-align: center;
    float: left;
  }

  .characterWrap__choonsik {
    color: #999;
    font-size: 13px;
    position: relative;
    display: inline-block;
    cursor: pointer;
  }

  .characterWrap__choonsik.active {
    color: #333;
    font-size: 13px;
    position: relative;
    display: inline-block;
    cursor: pointer;
  }

  .characterWrap__ryan {
    color: #999;
    font-size: 13px;
    position: relative;
    display: inline-block;
    cursor: pointer;
  }

  .characterWrap__ryan.active {
    color: #333;
    font-size: 13px;
    position: relative;
    display: inline-block;
    cursor: pointer;
  }

  .characterWrap__apeach {
    color: #999;
    font-size: 13px;
    position: relative;
    display: inline-block;
    cursor: pointer;
  }

  .characterWrap__apeach.active {
    color: #333;
    font-size: 13px;
    position: relative;
    display: inline-block;
    cursor: pointer;
  }

  .choonsik {
    background-position: 0 17.647059%;
    background-size: 100%;
    display: block;
    transition: hover 0.2s;
    margin-bottom: 5px;
    background-image: url(https://www.kakaofriendsgolf.com/img/[email protected]);
    background-repeat: no-repeat;
    width: 70px;
    height: 70px;
  }

  .choonsik.active {
    background-position: 0 11.764706%;
    background-size: 100%;
    display: block;
    transition: hover 0.2s;
    margin-bottom: 5px;
    background-image: url(https://www.kakaofriendsgolf.com/img/[email protected]);
    background-repeat: no-repeat;
    width: 70px;
    height: 70px;
  }

  .ryan {
    background-position: 0 88.235295%;
    background-size: 100%;
    display: block;
    transition: hover 0.2s;
    margin-bottom: 5px;
    background-image: url(https://www.kakaofriendsgolf.com/img/[email protected]);
    background-repeat: no-repeat;
    width: 70px;
    height: 70px;
  }

  .ryan.active {
    background-position: 0 82.352941%;
    background-size: 100%;
    display: block;
    transition: hover 0.2s;
    margin-bottom: 5px;
    background-image: url(https://www.kakaofriendsgolf.com/img/[email protected]);
    background-repeat: no-repeat;
    width: 70px;
    height: 70px;
  }

  .apeach {
    background-position: 0 5.882353%;
    background-size: 100%;
    display: block;
    transition: hover 0.2s;
    margin-bottom: 5px;
    background-image: url(https://www.kakaofriendsgolf.com/img/[email protected]);
    background-repeat: no-repeat;
    width: 70px;
    height: 70px;
  }

  .apeach.active {
    background-position: 0 0%;
    background-size: 100%;
    display: block;
    transition: hover 0.2s;
    margin-bottom: 5px;
    background-image: url(https://www.kakaofriendsgolf.com/img/[email protected]);
    background-repeat: no-repeat;
    width: 70px;
    height: 70px;
  }
`;

codesandbox

https://codesandbox.io/s/characterselect-4o6he0?file=/src/App.js

CodePudding user response:

Looked at the CodeSendbox. Looks nice!

If I understood correctly, your problem is that when you click any other icon without hovering on the first one, the first one doesn't get grayed out.

change following line

const [choonsik, setChoonsik] = useState(true);

to

const [choonsik, setChoonsik] = useState(false);
  • Related