防止React Router在按下后退按钮时重新加载API调用。Reactjs

3

有两个页面 - 一个主要页面列出元素,另一个页面详细描述元素。使用了React-Router。

<Switch>
    <Route exact path="/" component={PokemonCardContainer} />
    <Route path="/pokemon/:pokemonName" component={Pokemon} />
</Switch>

在列表主页面,会生成一个请求API,返回20个元素。当我们到达列表末尾时,API请求会更新-加载另外20个项目等等。enter image description here 详细描述页面由按钮“I Choose You!”实现。
<Link to={`pokemon/${pokemonName}`}>
   {pokemonName}, I Choose You!
</Link>

在详细描述页面上有一个“返回主页”的按钮。
const handleGoToHomePage = () => {
    props.history.push({
    pathname: "/",
   });
 };

因此,当我按返回到主页时,会发生新的API请求,我会回到页面顶部。但是我需要返回到我点击的列表元素。例如,如果我点击了第60个元素,则需要返回到该元素。我理解当我返回到主页时需要中断API请求?
      /* States */
      const [pokemons, setPokemons] = useState([]); 
      const [loading, setLoading] = useState(true);
      const [error, setError] = useState(false);
      const [currentPage, setCurrentPage] = useState(
        "https://pokeapi.co/api/v2/pokemon"
      );
      const [nextPage, setNextPage] = useState("");
      const [hasMore, setHasMore] = useState(false);
      useEffect(() => {
        let cancel;
        const fetchData = () => {
          setLoading(true);
          setError(false);
          Axios({
            method: "GET",
            url: currentPage,
            cancelToken: new Axios.CancelToken((c) => (cancel = c)),
          })
          .then((res) => {
            setPokemons((prevPokemons) => {
            return [...prevPokemons, ...res.data.results];
          });
            setNextPage(res.data.next);
            setHasMore(res.data.results.length > 0);
            setLoading(false);
          })
          .catch((error) => {
            if (Axios.isCancel(error)) return;
            setError(true);
          });
        };
      fetchData();
      return () => cancel();
    }, [currentPage]);
1个回答

0

我看到两种可能性,

第一种是在未卸载的父组件中进行API调用(例如菜单或主组件)。

第二种是使用类似Redux的存储来保存数据。如果您的应用程序很复杂,并且需要处理在组件之间共享的复杂状态,则我会选择这个选项。


谢谢您的评论!我刚开始学习react.js,还没有学习redux),我的应用程序是最简单的。在PokemonCardContainer内部发生api请求,形成一个新数组,并基于它使用map()构建元素列表(<PokemonCard />)。我需要在其他地方做api吗?但我没有上面的组件。 - kostya
你能在你的路由组件中实现它吗?然后你可以使用 render prop 将结果作为参数传递。 - Charles dB
我创建了一个新组件,在其中进行了API请求,插入了路由并传递了参数。 <Switch> <Route exact path="/" render={() => ( <PokemonCardContainer pokemons={pokemons} search={search} loading={loading} error={error} lastPokemonElementRef={lastPokemonElementRef} handleSearch={handleSearch} /> )} /> <Route path="/pokemon/:pokemonName" component={Pokemon} /> </Switch>。在返回时,不会发生新的请求,但页面会跳转到开头。 - kostya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接