为什么我的状态在鼠标悬停时不断更新,而它是一个单击事件?

huangapple go评论59阅读模式
英文:

Why is my state being updated constantly on hover when it's an onClick event?

问题

I put a console.log outside of my useEffect that retrieves a youtube url and see that anytime I hover in or out of the parent div, it seems to be retrieving a URL. This is resulting in lots of wasted Youtube API calls, so I'm wondering what the deal is?

It should just be calling my handlePlay function on click of the react icon, which then sets the selectedTrack state. I mean, that does work, but it's also got the hovering issue.

This is my code:

    const [hovered, setHovered] = useState(false);
    const [selectedTrack, setSelectedTrack] = useState<{ artist: string, title: string } | null>(null)
    const [youtubeURL, setYoutubeURL] = useState<string>('')

    const handlePlay = (title: string, artist: string) => {
        setSelectedTrack({ title, artist });
        console.log('clicked')
      };

    useEffect(() => {

        const getSongURL = async () => {
            if (selectedTrack) 
            try {
                const encodedTitle = encodeURI(selectedTrack.title.toLowerCase());
                const encodedArtist = encodeURI(selectedTrack.artist.toLowerCase());
                const songURL = await axios.get(`http://localhost:8080/api/v1/songdata/req_song/${encodedTitle}%20${encodedArtist}`);
                setYoutubeURL(songURL?.data?.id)
            } catch (error) {
                console.log("Error finding album details:", error);
              }
        }

        getSongURL();

    }, [selectedTrack])

    console.log(youtubeURL)

    return (
        <>
            <ul className='list-none m-0 py-0 px-[35px] relative'>
                <li className='box-border'>
                     <div className='flex justify-between items-center py-0 px-[15px]'>
                        {/* Inner details of block*/}
                            <div className={`group w-full flex justify-between box-border items-center rounded-lg hover:bg-[#4c426e] cursor-pointer self-stretch min-w-0 h-[50px] p-0 mb-2 relative`} 
                                onMouseEnter={() => setHovered(true)}
                                onMouseLeave={() => setHovered(false)}>
                                <div className={`w-full text-[12px] min-w-[35px] max-w-[35px] text-left ml-2 self-center shrink text-lg text-[#989898] relative`}>
                                    <div className={`absolute top-0 left-0 w-full h-full flex items-center justify-center transition-all ease-in-out duration-300`}>
                                        <span style={{ opacity: hovered ? 0 : 100 }} className={`absolute top-0 left-0 w-full h-full flex items-center justify-center transition-all ease-in-out duration-300`}>
                                            {number}
                                        </span>
                                        <span style={{ opacity: hovered ? 100 : 0 }} className={`absolute bottom-0 left-0 w-full h-full flex items-center justify-center transition-all ease-in-out duration-300`}>
                                            <FaPlay onClick={() => handlePlay(title, artist)}/>
                                        </span>
                                    </div>
                                </div>
                            </div>
                        </li>
                    </ul>           
        </>
    )
}

It almost feels like the onMouseEnter and Leave commands are somehow affecting it, but the onClick event shouldn't even be referencing hovering, so how is it constantly calling my handlePlay function just on hover?

英文:

I put a console.log outside of my useEffect that retrieves a youtube url and see that anytime I hover in or out of the parent div, it seems to be retrieving a URL. This is resulting in lots of wasted Youtube API calls, so I'm wondering what the deal is?

It should just be calling my handlePlay function on click of the <FaPlay> react icon, which then sets the selectedTrack state. I mean, that does work, but it's also got the hovering issue.

This is my code:


const [hovered, setHovered] = useState(false);
const [selectedTrack, setSelectedTrack] = useState&lt;{ artist: string, title: string } | null&gt;(null)
const [youtubeURL, setYoutubeURL] = useState&lt;string&gt;(&#39;&#39;)
const handlePlay = (title: string, artist: string) =&gt; {
setSelectedTrack({ title, artist });
console.log(&#39;clicked&#39;)
};
useEffect(() =&gt; {
const getSongURL = async () =&gt; {
if (selectedTrack) 
try {
const encodedTitle = encodeURI(selectedTrack.title.toLowerCase());
const encodedArtist = encodeURI(selectedTrack.artist.toLowerCase());
const songURL = await axios.get(`http://localhost:8080/api/v1/songdata/req_song/${encodedTitle}%20${encodedArtist}`);
setYoutubeURL(songURL?.data?.id)
} catch (error) {
console.log(&quot;Error finding album details:&quot;, error);
}
}
getSongURL();
}, [selectedTrack])
console.log(youtubeURL)
return (
&lt;&gt;
&lt;ul className=&#39;list-none m-0 py-0 px-[35px] relative&#39;&gt;
&lt;li className=&#39;box-border&#39;&gt;
&lt;div className=&#39;flex justify-between items-center py-0 px-[15px]&#39;&gt;
{/* Inner details of block*/}
&lt;div className={`group w-full flex justify-between box-border items-center rounded-lg hover:bg-[#4c426e] cursor-pointer self-stretch min-w-0 h-[50px] p-0 mb-2 relative`} 
onMouseEnter={() =&gt; setHovered(true)}
onMouseLeave={() =&gt; setHovered(false)}&gt;
&lt;div className={`w-full text-[12px] min-w-[35px] max-w-[35px] text-left ml-2 self-center shrink text-lg text-[#989898] relative`}&gt;
&lt;div className={`absolute top-0 left-0 w-full h-full flex items-center justify-center transition-all ease-in-out duration-300`}&gt;
&lt;span style={{ opacity: hovered ? 0 : 100 }} className={`absolute top-0 left-0 w-full h-full flex items-center justify-center transition-all ease-in-out duration-300`} &gt;
{number}
&lt;/span&gt;
&lt;span style={{ opacity: hovered ? 100 : 0 }} className={`absolute bottom-0 left-0 w-full h-full flex items-center justify-center transition-all ease-in-out duration-300`} &gt;
&lt;FaPlay onClick={() =&gt; handlePlay(title, artist)}/&gt;
&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;           
&lt;/&gt;
)
}

It almost feels like the onMouseEnter and Leave commands are somehow affecting it, but the onClick event shouldn't even be referencing hovering, so how is it constantly calling my handlePlay function just on hover?

答案1

得分: 0

你能否在CodeSandbox中提供你的代码?
另外,我会将getSongURL方法放在useEffect钩子之外。

英文:

Could you please provide your code in a CodeSandbox?
Also, I'd place the getSongURL method outside the useEffect hook.

答案2

得分: 0

我找到了一个解决方案,它告诉我,我的样式确实搞乱了一切。我摒弃了 onMouseEnter 和 onMouseLeave 的调用,并更改了样式,使其不再依赖于每个样式中的状态,就像这样:

style={{ opacity: hovered ? 100 : 0 }}

而是只需将其更改为 tailwindcss,根本不依赖于状态:

opacity-0 group-hover:opacity-100

就是这么简单。简单得让我抓了几个小时头发,但... 简单。

英文:

I figured out a solution that shows me that my styling was really messing with things. I got rid of the onMouseEnter and onMouseLeave calls and changed the styling so that instead of depending on state in each styling like this:

> style={{ opacity: hovered ? 100 : 0 }}

I instead just changed it to tailwindcss to not depend on a state at all:

> opacity-0 group-hover:opacity-100

Simple as that. Simple as in I was pulling my hair out for a few hours, but... simple.

huangapple
  • 本文由 发表于 2023年3月7日 17:34:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75660179.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定