【问题标题】:State Variables become null When UseEffect hook is used使用 UseEffect 挂钩时,状态变量变为空
【发布时间】:2021-11-02 01:21:01
【问题描述】:

每当用户使用以下内容到达底部时,我都会尝试发出新请求;

useEffect(() => {
    const scrolling_function = () => {
      if((window.innerHeight + window.scrollY) >= document.body.offsetHeight-10){
        window.removeEventListener('scroll',scrolling_function)
        getMoviesFromApi()
      }
    }
    window.addEventListener('scroll', scrolling_function);
}, [])

但是我定义的状态对象,比如:

const[selectedGenres, setSelectedGenres] = useState(new Set())

我的useEffect 钩子内部的所有内容都变得未定义,因此我的getMoviesFromApi() 方法无法正常工作。

我的问题是,这是预期的行为吗?如果是这样,我该如何克服它?

getmoviesfromapi 方法:

const getMoviesFromApi = async () => {
    setLoading(true)
    let init, end;
    if(initialYear>endYear) {
      init = endYear
      end = initialYear
    } else {
      init = initialYear
      end = endYear
    }
    let res =await fetchMovies(init, end)
    setLoading(false)
    setMovies(res.results)
  }

fetchMovies 方法:

const fetchMovies = async (startYear, endYear) => {
    let res;

    res = [];
    let genreQuery = "";
    let serviceQuery = "";
    for (let it = selectedGenres.values(), val= null; val=it.next().value; ) {
      genreQuery += "&genre=" + val;
    }
    for (let it = selectedServices.values(), val= null; val=it.next().value; ) {
      serviceQuery += "&service=" + val;
    }

    let countryQuery = "?country="+country;
    let yearQuery = "&year_min="+ startYear +"&year_max=" + endYear;
    let typeQuery = "&type=" + (isMovie ? "movie" : "series");
    let url = api_url + countryQuery + serviceQuery + typeQuery +"&order_by=year" + yearQuery
          + genreQuery + "&page=1&desc=true&language=en&output_language=en"

    await fetch(url, {
      "method": "GET",
    }).then(response => {
          res= response.json()
        })
        .catch(err => {
          console.error(err);
        });
    return res;
  };

【问题讨论】:

  • getMoviesFromApi的代码是什么?这是在哪里定义的?
  • 显示整个组件,我们无法用这么多的代码来判断。此外,您需要在 useEffect 挂钩中返回一个“清理”函数,该函数也会删除该事件侦听器。
  • @TJBlackman 感谢您的评论。我想我应该添加状态对象或函数作为依赖项并使用 useCallBack() 定义函数,这解决了我的问题。但是 fetch 方法被调用了不止一次,这可能与那个清理功能有关?你能详细说明一下吗?
  • @TJBlackman nvm ,明白了,一个删除事件监听器的返回函数,就像你说的:d

标签: javascript reactjs react-hooks


【解决方案1】:

您应该将必要的状态对象和函数添加到依赖项中,并使用 useCallBack 调用这些函数。您可以通过安装 eslint-plugin-react-hooks 作为开发依赖项来确保您做对了。你还需要一个清理函数来为你的效果挂钩。

useEffect( () =>{
    const scrolling_function = async () => {
      if((window.innerHeight + window.scrollY) >= document.body.offsetHeight-10){
        await getMoviesFromApi(false);
      }
    }

    window.addEventListener('scroll', scrolling_function);
    return function cleanUp() { //don't forget to clean up
      window.removeEventListener('scroll',scrolling_function);
    }
  }, [getMoviesFromApi]); //add method as dependency!

//...

const getMoviesFromApi = useCallback () => { //useCallBack is needed here!
   ...
}

【讨论】:

    猜你喜欢
    • 2022-01-17
    • 2021-09-14
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 2019-05-07
    • 2019-12-27
    • 2021-06-16
    • 2023-04-04
    相关资源
    最近更新 更多