按下后退按钮时防止反应路由器重新加载 API 调用。反应

Posted

技术标签:

【中文标题】按下后退按钮时防止反应路由器重新加载 API 调用。反应【英文标题】:Prevent react router reloading API call when pressing back button. Reactjs 【发布时间】:2020-07-18 11:12:55 【问题描述】:

有两个页面 - 主页面包含元素列表,另一个页面包含元素的详细描述。使用 react-router。

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

在带有列表的主页上,会生成一个请求 api,它返回 20 个元素。此外,当我们到达列表的末尾时,更新了 api 请求 - 加载了另外 20 个项目,等等。

详细描述页面由“我选择你!”按钮实现

<Link to=`pokemon/$pokemonName`>
   pokemonName, I Choose You!
</Link>

在详细描述页面上有一个“返回首页”按钮

const handleGoToHomePage = () => 
    props.history.push(
    pathname: "/",
   );
 ;

因此,当我按返回到主页时,会出现一个新的 api 请求,然后我到达页面顶部。但我需要返回到我单击的列表元素。例如,如果我点击了第 60 个元素,我需要返回它。了解返回main时需要中断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】:

我看到了两种可能性,

您在未卸载的父组件(例如菜单或主组件)中进行 API 调用

或者您使用Redux 之类的方式将数据保存在存储中。如果您的应用程序很复杂并且需要处理组件之间共享的复杂状态,我会选择此选项。

【讨论】:

感谢您的评论!刚开始学react.js,还没学过redux),我的应用是最简单的。在PokemonCardContainer内部,发生api请求,形成一个新数组,并在此基础上使用map()构建元素列表(&lt;PokemonCard /&gt;)。我需要在上面的某个地方做api吗?但我没有上述组件。 你能在你的路由器组件里做吗?然后,您可以使用 render prop 将结果作为参数传递 我创建了一个新组件,并在其中发出了 API 请求。在其中插入路由,传递参数。 &lt;Switch&gt; &lt;Route exact path="/" render=() =&gt; ( &lt;PokemonCardContainer pokemons=pokemons search=search loading=loading error=error lastPokemonElementRef=lastPokemonElementRef handleSearch=handleSearch /&gt; ) /&gt; &lt;Route path="/pokemon/:pokemonName" component=Pokemon /&gt; &lt;/Switch&gt;。在返回时,不会发生新的请求。但页面跳转到开头。

以上是关于按下后退按钮时防止反应路由器重新加载 API 调用。反应的主要内容,如果未能解决你的问题,请参考以下文章

Android后退按钮处理程序反应本机路由器通量

按下后退按钮时正在重新创建 Listview 片段

按下后退按钮时强制重新加载/刷新

在浏览器的后退按钮上反应路由器历史记录

使用浏览器后退按钮时如何强制重新加载页面?

按下浏览器重新加载按钮时防止变量丢失[重复]