Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将基于类的组件重构为功能组件_Javascript_Reactjs_React Hooks_Infinite Scroll_Use Effect - Fatal编程技术网

Javascript 将基于类的组件重构为功能组件

Javascript 将基于类的组件重构为功能组件,javascript,reactjs,react-hooks,infinite-scroll,use-effect,Javascript,Reactjs,React Hooks,Infinite Scroll,Use Effect,TL;DR:我正在尝试将我基于类的应用程序组件重构为功能组件,我在useEffect钩子上得到了一些意想不到的结果 我对React还比较陌生,我用OMDB API搜索电影的应用程序版本是基于类的。它工作得很好,所以在进入redux之前,我想在使用钩子和上下文方面进行更多的练习 在我的类组件中,我有以下代码: componentDidMount = () => { window.onscroll = this.handleScroll; }; handleScroll =

TL;DR:我正在尝试将我基于类的应用程序组件重构为功能组件,我在useEffect钩子上得到了一些意想不到的结果

我对React还比较陌生,我用OMDB API搜索电影的应用程序版本是基于类的。它工作得很好,所以在进入redux之前,我想在使用钩子和上下文方面进行更多的练习

在我的类组件中,我有以下代码:

componentDidMount = () => {
    window.onscroll = this.handleScroll;
  };

  handleScroll = () => {
    if (!this.state.movies.loading) {
      if (getScrollDownPercentage(window) > 0.8) {
        const nextPage = this.state.movies.page + 1;
        this.searchMovies(this.state.movies.searchValue, nextPage);
        this.setState({
          ...this.state,
          movies: {
            ...this.state.movies,
            page: nextPage,
          },
        });
      }
    }
  };

  searchMovies = (str, page = 1) => {
    const existingMovies =
      this.state.movies.data.length && this.state.movies.searchValue === str
        ? this.state.movies.data
        : [];
    this.setState({
      ...this.state,
      movies: {
        ...this.state.movies,
        loading: true,
      },
    });
    axios
      .get(`${process.env.REACT_APP_ENDPOINT}s=${str}&page=${page}`)
      .then((response) => {
        if (response.data.Response === "True") {
          this.setState({
            ...this.state,
            movies: {
              ...this.state.movies,
              loading: false,
              searchValue: str,
              data: [...existingMovies, ...response.data.Search],
            },
          });
        }
      });
  };
重构后,我有以下感觉不太干净的代码(与我希望实现的相反)

当我到达页面末尾时,我会看到一个不间断的axios调用流在第2页和第3页之间切换

如果我没有错的话,它就不起作用了,因为setState是异步运行的,而且我的页面上不断有更新

  useEffect(() => {
    window.onscroll = () => {
      handleScroll();
    };
    if (searchValue) {
      console.log(page);
      searchMovies(searchValue, page);
    }
    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, [searchValue, page]);

  const handleScroll = () => {
    if (!loading && searchValue) {
      if (getScrollDownPercentage(window) > 0.7) {
        setState({
          ...state,
          movies: {
            ...state.movies,
            page: page + 1,
          },
        });
      }
    }
  };

  const searchMovies = (str, page = 1) => {
    const existingMovies = data.length && prevSearchValue === str ? data : [];
    setState({
      ...state,
      movies: {
        ...state.movies,
        loading: true,
      },
    });
    axios
      .get(`${process.env.REACT_APP_ENDPOINT2}s=${str}&page=${page}`)
      .then((response) => {
        if (response.data.Response === "True") {
          setState({
            ...state,
            movies: {
              ...state.movies,
              loading: false,
              searchValue: str,
              data: [...existingMovies, ...response.data.Search],
            },
          });
        } else {
          setState({
            ...state,
            movies: {
              ...state.movies,
              loading: false,
              error: true,
            },
          });
        }
      });
  };
我希望我包括了一切(也不要太多),以澄清我的问题。寻找一些反应向导


编辑:再指定一点问题,并用粗体显示。

快速修复方法是使用空数组作为第二个参数,以避免无限循环

useEffect(() => {
    //your code
  },[]);

根据您的回复,我想您应该做多个
useffects
:一个用于搜索电影,另一个用于滚动设置

useffect(()=>{
window.onscroll=()=>{
handleScroll();
};
return()=>{
window.removeEventListener(“滚动”,handleScroll);
};
}, []);
useffect(()=>{
如果(搜索值){
控制台日志(第页);
searchMovies(searchValue,第页);
}
},[searchValue,第页])

问题是:我没有在componentDidMount上搜索电影。只有当searchValue发生更改时,我才需要searchValue作为依赖项,将页面从依赖项中删除也会破坏代码。当滚动“我的组件”时,如果您在searchMovie函数中更新搜索电影值后创建了无限循环,则每次更改这些值时,useEffect都会运行。这已经运行得更好了。我必须在第一个钩子上添加searchValue作为依赖项,否则handlescroll函数的值仍然为空。现在我的组件刷新有问题…你应该解除onScroll处理程序的抖动。我建议使用lodash/debounce