React 路由器在刷新时不呈现单个 id 路由

React router is not rendering single id routes on refresh

我正在做一个个人项目,几天以来我一直被反应路由器问题所困扰。

我正在获取 API 并尝试使用单个 ID 渲染路线,所以当我点击卡片时 link 一切正常,但一旦尝试渲染link 在新选项卡上手动操作,例如我收到控制台错误

TypeError: Cannot read property 'position_name' of undefined

 | const Articles = ({ location }) => (
  5 |   <ArticleComponent
> 6 |     position_name={location.state.position_name}
  7 |     workplace_name={location.state.workplace_name}

这是我在 APP.js 文件

上的路线
    <Switch>
      <Route exact path="/" component={JobCard} />
      <Route path="/jobs/:_id" component={Articles} />
    </Switch>

以及我获取卡片的组件。

  <div key={job._id} className="blog-card">
                    <div className="description">
                      <Link
                        className="link-apply"
                        to={{
                          pathname: `/jobs/${job._id}`,
                          state: job
                        }}
                      >
                        <h5 className="position-name">{job.position_name}</h5>
                        <p className="place">{job.workplace_name}</p>
                        <p className="location-job">{job.location}</p>
                      </Link>
                    </div>

所以我想要实现的是能够在我手动键入 link 时呈现文章,例如:http://localhost:3000/jobs/5ccc770c6ac54350001f0954

但由于某些原因,只有当我点击卡片时它才会呈现。

在此先感谢您的帮助

But it's only rendering when i click on the card for some reasons.

当您点击卡片中的 <Link> 时,您可以看到您的请求如下所示:

<Link
  className="link-apply"
  to={{
    pathname: `/jobs/${job._id}`,
    state: job
  }}
>

执行此操作时,您的请求包含 2 个信息:

  1. 它想去的路径pathname
  2. 它会发送一个状态,其中包含您的 job

所以在你的组件中

const Articles = ({ location }) => (
  <ArticleComponent
    position_name={location.state.position_name}
    workplace_name={location.state.workplace_name}
    . . .
  />
);

location 对象如下所示:

location = {
  pathname: ‘your_url’,
  state: {
    position_name: ‘your_string’,
    workplace_name: ‘your_string’
    . . .
  }
}

这就是调用 location.state.position_name 有效的原因。但是,当您手动输入 URL 时,位置只会显示为:

location = {
  pathname: ‘your_url’
}

因为,你居然没有通过任何状态!这是不可能实现的,您不能通过输入 URL 来向您的位置道具添加任何内容。那么,让我们开始吧。

解决方案

您需要另一种方式来获取您的州信息。由于您可以从数据库中检索任何内容,因此应该执行以下操作。只需更改您的 <Article> 组件:

Article.js

// You can pass the whole props or destructure the ones you need
// like you did before. In my example, I don’t nee anything so I
// just leave it blank
const Articles = () => {
  // Not the best method but it works everywhere, since I don’t know
  // your whole project structure. Read below for more information.
  const pathname = window.location.pathname.split(‘/‘);
  const job_id = pathname[pathname.length - 1];

  // Make your query here
  // Assume query() is a function that return a job with given id
  // from your database
  const job = query(job_id);
  let position_name;
  let workplace_name;

  // If query was successful
  if (job) {
    position_name = job.position_name;
    workplace_name = job.workplace_name;
  }

  return (
    <ArticleComponent
      position_name={position_name}
      workplace_name={workplace_name}
      . . .
    />
  );
};

因此,您只需 job_id 即可检索所需的信息,并且您允许用户直接从 URL.

进行查询

关于路径名的注意事项

我从 window.location 中检索到 job_id,这是默认的 javascript URL 解析器。然而,它有点丑,更不用说它的可扩展性不强了。

根据您的项目树的结构,如果您的元素连接到路由器,您可以使用 query_string 库,如 中所述(注意一些方法不在最近的 React 版本中不再工作)。

由于您的用户可能会出错(例如,输入不存在的 ID),您需要处理查询中的错误,例如返回空值,或重定向到 404如果查询没有成功。