【问题标题】:Prevent react router reloading API call when pressing back button. Reactjs按下后退按钮时防止反应路由器重新加载 API 调用。反应
【发布时间】: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]);

【问题讨论】:

    标签: javascript reactjs api react-router


    【解决方案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;。在返回时,不会发生新的请求。但页面跳转到开头。
    猜你喜欢
    • 2017-03-08
    • 1970-01-01
    • 2020-10-29
    • 2016-07-08
    • 1970-01-01
    • 2020-12-20
    • 2015-07-15
    • 2019-01-15
    • 2019-08-23
    相关资源
    最近更新 更多