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);