响应路由器中的matchPath似乎未考虑基本名称

时间:2019-05-25 06:11:25

标签: reactjs react-router

我正在调查React-router-dom版本5.0.0的一个错误,并且活动类未应用于活动链接。

当我们的基础名称为conf时,它可以在开发中使用,但是在我们的开发环境中,该基础名称设置为`/ some / basename/'。

如果我直接这样称呼private void readChats() { mUsers = new ArrayList<>(); databaseReference = FirebaseDatabase.getInstance().getReference("Users"); databaseReference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { try { mUsers.clear(); for (DataSnapshot snapshot : dataSnapshot.getChildren()) { User user = snapshot.getValue(User.class); //displaying 1 user from chat for (String id : usersList) { if (user.getUserId().equals(id)) { if (mUsers.size() != 0) { for (User user1 : mUsers) { if (!user.getUserId().equals(user1.getUserId())) { mUsers.add(user); } } } else { mUsers.add(user); } } } }//end of for userAdapter = new UserAdapter(getContext(), mUsers); recyclerView.setAdapter(userAdapter); } catch (Exception e) { Toast.makeText(getContext(), e.toString(), Toast.LENGTH_SHORT).show(); } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { } }); }//end of readChats //this is the method

/

然后返回null,如果我这样调用matchpath,则会得到一个匹配项:

matchPath

所以看来matchPath("/some/basename/business", { exact: true, location: undefined, path: "\/business", strict: undefined }) 没有使用matchPath("/business", { exact: true, location: undefined, path: "\/business", strict: undefined }) ,因为在尝试调试代码后,我看到matchPath调用了basename并创建了此正则表达式:

matchPath

该代码似乎仅使用pathToRegexp属性,而不使用location.pathname。

我试图实现自己的/^\/business\/?$/i 方法来记录正在发生的事情:

path

isActive在环境中始终为null,但在开发中效果很好。

为什么会这样?

2 个答案:

答案 0 :(得分:4)

HTML概念

这实际上是react-router的一大优点,因为在开发阶段您不知道项目将在何处部署。它可能部署在以下位置:

  • 主域
  • 子域
  • 子目录

所以最好的方法是在 基本网址不可知的方式。实际上,React-Router中的basename并不是什么新鲜事物,我们在HTML中拥有<base>头标记:

<head>
   <base href="https://www.yoursite.com/some/basename/" target="https://www.yoursite.com/other/">
</head>

此标记意味着页面中的所有相对URL都将添加https://www.yoursite.com/some/basename/,例如:

<img src="header.jpg">

将与

相同
<img src="https://www.yoursite.com/some/basename/header.jpg">

以及所有相关链接和表单操作也将附加href


反应路由器

React-Router基本上使用此概念(但是,不是基本标记),因此当您在主`中设置basename时,以下元素将一无所知

>
  • <Route>
  • <Link>
  • <Redirect>
  • matchPath

因此,当您具有这样的链接时:

<Link to="/page2" />

它实际上将重定向到/some/basename/page2


基本名称

  • React-Router Docs建议A properly formatted basename should have a leading slash, but no trailing slash.(例如 / some / business )。但是,在大多数现代浏览器中,这都没有关系。

matchPath

现在让我们谈谈matchPath。如前所述,matchPath对基本名称一无所知,因此请牢记以下几点:

  • 确保输入的URL 在其中包含基本名称。
  • 不要不要使用window.location.pathname,而应使用React-Router位置道具

那你应该没事。因此,无论您使用哪种环境(dev / prod),它都将始终有效:

matchPath(props.location.pathname, {
    path: '/business',
    exact: true,
});

注释

如果牢记所有这些,您会在整个项目中遇到一些问题(包括所有链接,所有重定向,所有路由以及matchPath),那么在生产环境中您的基本名称设置错误。

答案 1 :(得分:0)

基于此github issue comment

  

basename来自<base href="/foo"> HTML元素,该元素   将basename应用于页面上的所有链接。在这种情况下,其余的   的HTML不能“了解”该基本网址;只是   自动添加到任何href。

     

类似地,Router中的基本名称是应用程序不需要的   知道关于。它只是<Link>'s到各种路线,并且不知道   basename被附加。

在使用mathPath时,如果使用Router提供的window.location.pathname而不是location.pathname,则会收到与您的路由匹配的路径名,而不是包含基本名的整个路径名。

matchPath(location.pathname, {
  exact: true,
  location: undefined,
  path: "\/business",
  strict: undefined
})

,如果路径为/some/basename/busines

,则以上内容将返回true