0

我正在尝试克隆 netflix,当我将鼠标悬停在电影图像上时,会出现该电影的预告片,当我将鼠标悬停在控制台中有许多相同的输出时,就会出现问题。我认为这个问题是因为我在地图内渲染,但我正在寻找避免这种情况的性能......我尝试使用 React.memo 但不起作用。

这是一个例子

在此处输入图像描述

我有一个父组件

function MovieList(props) {
...
    <Movies movies={netflixMovies} title="Movie Feature" />
}

在子组件内部,我有以下内容

function Movie(props) {
...
const showMiniVideo = (id) => {
    setTimeout(() => {
      fetchYoutubeVideo(id) // Function who give me the ID of youtube video
        .then(res => {
          if (res.results.length === 0) { // If doesn't exist a video i set existVideo false
            setExistVideo(false)
            return setIdYoutubeVideo() // IdYoutubeVideo none
          }
          else {
            setExistVideo(true) // If exist a video i set existVideo true
            res.results.map(thriler => {
              return setIdYoutubeVideo(thriler.key) // IdYoutubeVideo id
            })
          }
        })
        .catch(err => {
          setExistVideo(false)
          console.error(err)
          return setIdYoutubeVideo()
        });
    }, 1000);
  }

...

return (
{movies.map(movie => (
              <div key={movie.id} className="tile">
                  <div onMouseOver={() => showMiniVideo(movie.id)} onMouseOut={stopMiniVideo}>
                    {idYoutubeVideo ?
                      (idMovie === movie.id ?
                        (existVideo ?
                          console.log("hay video")
                          :
                          console.log("no hay video")
                        )
                        :
                        console.log("no es el id")
                      )
                      :
                      <svg style={{ color: 'white' }} width="1.5vw" height="1.5vw" viewBox="0 0 16 16" className="bi bi-play-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                        <path d="M11.596 8.697l-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 0 1 0 1.393z" />
                      </svg>
                    }
                  </div>
                </div>
              </div>
            ))}
)}

有人有想法吗?我将不胜感激任何帮助

4

3 回答 3

0

每次将鼠标悬停在 showMiniVideo() 上时,执行并获取和设置状态都会导致重新渲染。当您在鼠标悬停时尝试保持旗帜。

但我会说console.log的最小数量=数组(电影)的长度,这是可以的。

如果不止于此,请使用类似这样的标志-

if(isMouseOver) return;

return (
{movies.map(movie => (
              <div key={movie.id} className="tile">
                  <div onMouseOver={() => showMiniVideo(movie.id)} onMouseOut={stopMiniVideo}>
                    {idYoutubeVideo ?
                      (idMovie === movie.id ?
                        (existVideo ?
                          console.log("hay video")
                          :
                          console.log("no hay video")
                        )
                        :
                        console.log("no es el id")
                      )
                      :
                      <svg style={{ color: 'white' }} width="1.5vw" height="1.5vw" viewBox="0 0 16 16" className="bi bi-play-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                        <path d="M11.596 8.697l-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 0 1 0 1.393z" />
                      </svg>
                    }
                  </div>
                </div>
              </div>
            ))}
)}

仅当在执行 showMiniVideo() 时更新所有状态时 isMouseOver 才应该为 false - setExistVideo,setIdYoutubeVideo...

于 2020-07-29T21:53:01.823 回答
0

Ciao,是的,你是对的:ReactonMouseOver的行为与普通 HTML 不同。在 HTML 中只会触发一次。在 React 中,当您第一次进入对象时肯定会触发,然后是不确定的次数(有时仅在您离开对象时,有时更多)。奇怪的!

要解决此问题,您可以使用debounce防止此行为的功能。这里有一个例子来解释如何使用debounce.

无论如何,谢谢,你指出了一些我不知道的事情!

于 2020-07-29T22:14:58.417 回答
0

我认为您遇到的问题是不了解 javascript 侦听器mouseover本身。每次将鼠标移到正在收听的元素上时,都会调用 Mouseover get(几乎)。您可能想要的是mouseenter并且mouseleave两者都存在于 react asonMouseEnteronMouseLeave. 这里的主要区别是它们都只触发一次,一旦指针进入元素区域,或者分别离开它。

顺便说一句,MDN 实际上在关于 mouseover 的文章中解释了这种行为。

请随时在评论中回复我,祝您编码愉快 =)

于 2020-07-29T21:36:04.260 回答