React路由器刷新元素在位置更改上

发布于 2025-02-13 01:37:39 字数 2519 浏览 0 评论 0原文

我的问题与这里的问题非常相似,但是该解决方案对我不起作用。 React Router不刷新

页面m使用React路由器v6)我有一系列我想使用相同代码的博客文章,但带有不同的URL并加载数据相同的API。使用同一博客()函数构建这些功能是有意义的,因此路由器指向同一元素。

import { Component, useState, useEffect } from "react";
import { Routes, Route, Link, useParams, useNavigate, useSearchParams, useLocation } from "react-router-dom";
function App() {
return (
<Header Title={"My blog"}>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="blog1" element={<Blog />} />
    <Route path="blog2" element={<Blog />} />
    <Route path="*" element={<NotFound />} />
  </Routes>
  </Header>
  );
}

使用博客功能类似于以下内容:

function Blog() {
  console.log(`blog re ran`);
  const [data, setData] = useState(null);
  const location = useLocation();
  const [count, setCount] = React.useState(0);
  var loaded = false;
  let routerpath = location.pathname;
  let routerpath2 = routerpath.substring(1);
  const timer = ms => new Promise(res => setTimeout(res, ms))
  async function load () { 
    for (var i = 0; i < 2; i++) {
    console.log(`Refresh timer: ${i}`);
    await timer(120000); // then the created Promise can be awaited
    setCount(0);
    console.log("Count reset.");
    loaded = false;
    }
  }
useEffect(() => {
    if (routerpath) {
    if (count == 0) {
      fetch(`https://api.example.com/api.php?route=${routerpath2}`)
        .then((Response) => {
          if (Response.ok) {
            return Response.json();
          }
          throw Response;
        })
        .then((data) => {
          setData(data);
          console.log("API call answered. {productId}");
          loaded = false;
          setCount(count + 1);
          console.log("Count incremented.");
load(); 
        })
    }, [data, count, location, location.pathname, routerpath ]);
 if (data) {
    if (loaded == false){
          console.log("Reloaded content.");
    return (
    <div>
{data.BlogPosts.map((BlogPost, i) => {
 return (
<Typography paragraph>{BlogPost.MainContent}</Typography>
);
}
</div>
  );
  load(); 
  loaded = true;
}
}

我必须添加计数常数和加载的var才能阻止该应用程序不断查询API,因此我这里不包含另一个功能,该功能在刷新之前等待2分钟。我认为它的使用及等待函数和计数/加载的VAR可以停止在页面更改上更改内容。我已经尝试将基于位置的依赖项添加到使用效果,并在博客功能开始时添加刷新,在控制台输出中,我可以多次看到“博客重新运行”消息,因此知道此代码是重新运行的i不明白为什么没有进行API呼叫。

My question is very similar to one here, but this solution didn't work for me.
React router doesn't refresh page

My default app has a router (I'm using react router v6) I have a series of blog posts which I want to use the same code but appear with a different URL and load data from the same API. It makes sense to use the same blog() function to build these so the router points to the same element.

import { Component, useState, useEffect } from "react";
import { Routes, Route, Link, useParams, useNavigate, useSearchParams, useLocation } from "react-router-dom";
function App() {
return (
<Header Title={"My blog"}>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="blog1" element={<Blog />} />
    <Route path="blog2" element={<Blog />} />
    <Route path="*" element={<NotFound />} />
  </Routes>
  </Header>
  );
}

with the blog function similar to the below:

function Blog() {
  console.log(`blog re ran`);
  const [data, setData] = useState(null);
  const location = useLocation();
  const [count, setCount] = React.useState(0);
  var loaded = false;
  let routerpath = location.pathname;
  let routerpath2 = routerpath.substring(1);
  const timer = ms => new Promise(res => setTimeout(res, ms))
  async function load () { 
    for (var i = 0; i < 2; i++) {
    console.log(`Refresh timer: ${i}`);
    await timer(120000); // then the created Promise can be awaited
    setCount(0);
    console.log("Count reset.");
    loaded = false;
    }
  }
useEffect(() => {
    if (routerpath) {
    if (count == 0) {
      fetch(`https://api.example.com/api.php?route=${routerpath2}`)
        .then((Response) => {
          if (Response.ok) {
            return Response.json();
          }
          throw Response;
        })
        .then((data) => {
          setData(data);
          console.log("API call answered. {productId}");
          loaded = false;
          setCount(count + 1);
          console.log("Count incremented.");
load(); 
        })
    }, [data, count, location, location.pathname, routerpath ]);
 if (data) {
    if (loaded == false){
          console.log("Reloaded content.");
    return (
    <div>
{data.BlogPosts.map((BlogPost, i) => {
 return (
<Typography paragraph>{BlogPost.MainContent}</Typography>
);
}
</div>
  );
  load(); 
  loaded = true;
}
}

I had to add the count constant and loaded var to stop the app from continuously querying the API, I have another function not included here which puts in a wait of 2 minutes before refreshing. I think its the use of the wait function and the count/loaded vars that stop the content changing on change of the page. I've tried adding location based dependencies to the useEffect, and adding a refresh at the start of the blog function, in the console output I can see the 'blog re ran' message multiple times so know that this code is re-run I don't understand why the api call isn't made .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不回头走下去 2025-02-20 01:37:39

似乎您不使用或不想使用动态路径路径,例如&lt; route path =“ /:blogid” element = {&lt; blog /&gt;} /&gt; < /< /代码> Blog组件将仅使用const {blogid} = useParams()并做出适当的提取请求。这将是类似于您链接到的其他帖子的解决方案。

如果您想像您一样使用两个单独的路由,那么我建议您仅将路由 querystring值作为道具传递。当路由 Prop更改时,它将触发usefeft挂钩以基于当前路由> ROUTE> ROUTE依赖关系值来灌输博客文章。

示例:

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="blog1" element={<Blog route="blog1" />} />
  <Route path="blog2" element={<Blog route="blog2" />} />
  <Route path="*" element={<NotFound />} />
</Routes>

博客

function Blog({ route }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(`https://api.example.com/api.php?route=${route}`)
      .then((response) => {
        if (!response.ok) {
          throw new Error('Network response was not OK');
        }
        return response.json();
      })
      .then((data) => {
        setData(data);
      })
      .catch(error => {
        // catch/handle any rejected Promises or thrown errors
      });
  }, [route]);

  return data?.BlogPosts?.length
    ? data.BlogPosts.map((post, i) => (
      <Typography key={post.id} paragraph>
        {post.MainContent}
      </Typography>
    ))
    : null;
}

It seems like you are not using, or don't want to use, a dynamic route path such as <Route path="/:blogId" element={<Blog />} /> where the Blog component would then just use const { blogId } = useParams() and make the appropriate fetch request. This would be the solution similar to the other SO post you linked to.

If you want to use two separate routes like you have then I'd suggest just passing in the route queryString value as a prop. When the route prop changes it will trigger the useEffect hook to refetch blog posts based on the current route dependency value.

Example:

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="blog1" element={<Blog route="blog1" />} />
  <Route path="blog2" element={<Blog route="blog2" />} />
  <Route path="*" element={<NotFound />} />
</Routes>

Blog

function Blog({ route }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(`https://api.example.com/api.php?route=${route}`)
      .then((response) => {
        if (!response.ok) {
          throw new Error('Network response was not OK');
        }
        return response.json();
      })
      .then((data) => {
        setData(data);
      })
      .catch(error => {
        // catch/handle any rejected Promises or thrown errors
      });
  }, [route]);

  return data?.BlogPosts?.length
    ? data.BlogPosts.map((post, i) => (
      <Typography key={post.id} paragraph>
        {post.MainContent}
      </Typography>
    ))
    : null;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文