【问题标题】:SetInterval in UseEffect without DelayUseEffect 中的 SetInterval 无延迟
【发布时间】:2021-08-05 11:37:16
【问题描述】:

我正在用 React 构建一个电影应用来练习。

首页有一个大横幅,上面有电影海报和电影信息,这个横幅的内容每5秒变化一次。我为此创建了这个函数:

 const [movie, setMovie] = useState('');     //const movie returns object of one random movie

  useEffect(() => {
    async function fetchData() {
      const request = await axios.get(requests.fetchNetflixOriginals);  
      setMovie(
        request.data.results[
          Math.floor(Math.random() * request.data.results.length)
        ]
      );
    }
    const interval = setInterval(() => {
      fetchData();
    }, 5000)
   return () => clearInterval(interval)   
  }, [movie]);

这个解决方案有一个问题:我第一次运行这个应用程序有5秒的延迟(由setInterval引起)。

所以我的问题是,是否有任何解决方案可以得到相同的行为,而且一开始就没有延迟?

我尝试了很多不同的解决方案,包括定义新状态,但所有这些都会导致错误或无限循环。

谢谢!

【问题讨论】:

    标签: javascript reactjs react-hooks setinterval use-effect


    【解决方案1】:

    定义区间时只需调用fetchData

    useEffect(() => {
        async function fetchData() {
            const request = await axios.get(requests.fetchNetflixOriginals);
            setMovie(
                request.data.results[
                Math.floor(Math.random() * request.data.results.length)
                ]
            );
        }
        fetchData();
        const interval = setInterval(fetchData, 5000)
        return () => clearInterval(interval)
    }, [movie]);
    

    【讨论】:

      【解决方案2】:

      是的,我已经尝试过这个解决方案,首先调用函数,然后设置一个时间间隔。 但结果是横幅开始有疯狂的行为。它在一秒钟内不断变化 10 倍。

      我附上了一个完整的更新组件代码,以确保我没有错过要发送的内容:

      const Banner = () => {
        const [movie, setMovie] = useState({});
      
        useEffect(() => {
          async function fetchData() {
              const request = await axios.get(requests.fetchNetflixOriginals);
              setMovie(
                  request.data.results[
                  Math.floor(Math.random() * request.data.results.length)
                  ]
              );
          }
          fetchData();
          const interval = setInterval(fetchData, 5000)
          return () => {
            clearInterval(interval)
          }
      }, [movie]);
      
        function truncate(str, n) {
          return str?.length > n ? str.substr(0, n - 1) + '...' : str;
        }
      
        return (
          <header
            className='banner'
            style={{
              backgroundSize: 'cover',
              backgroundImage: `url(https://image.tmdb.org/t/p/original/${movie?.backdrop_path})`, 
              backgroundPosition: 'center center',
            }}
          >
            <div className='banner__contents'>
              <h1 className='banner__title'>
                {movie?.title || movie?.name || movie?.original_name}
              </h1>
              <div className='banner__buttons'>
                <button className='banner__button'>Play</button>
                <button className='banner__button'>My List</button>
              </div>
              <h1 className='banner__description'>
                {truncate(movie?.overview, 120)}
              </h1>
            </div>
            <div className='banner--fadeBottom'></div>
          </header>
        );
      };
      

      任何想法应该导致它/如何防止这种行为?

      【讨论】:

        【解决方案3】:

        我在添加另一个 useEffect 挂钩后解决了这个问题。但我不确定它是否会调用其他问题。

        useEffect(() => { 
          fetchData()
        })
        

        【讨论】:

          猜你喜欢
          • 2020-09-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多