React-Router 基础知识

React-Router怎么获取历史对象?

在React Router中,可以通过useHistory hook获取历史对象。
例如:

jsx
import { useHistory } from 'react-router-dom';

function MyComponent() {
  const history = useHistory();
  
  function handleClick() {
    history.push('/some/other/path');
  }
  
  return <button onClick={handleClick}>Go to some path</button>
}

useHistory hook会返回一个history对象,该对象有以下方法:

  • push(path, [state]) - 将新入栈history条目,并导航到该路径
  • replace(path, [state]) - 替换当前history条目,并导航到该路径
  • go(n) - 将history前进n步或后退n步
  • goBack() - 后退一步
  • goForward() - 前进一步
  • block(prompt) - 阻止跳转(功能和浏览器里的阻止跳转一样)
    所以在这个例子中,当点击按钮时,会使用history.push()导航到/some/other/path路径。
    除了useHistory外,你也可以从路由器中直接获取history对象,例如:
jsx
const history = useHistory();

<Router history={history}>
  ...  
</Router>

React-Router怎么获取URL的参数?

在React Router中,可以通过useParams hook获取URL中的参数。
例如,对于路径/users/1,可以这样获取用户ID:

jsx
import { useParams } from 'react-router-dom';

function User() {
  const { id } = useParams();
  return <p>User ID: {id}</p> 
}

useParams hook会返回一个对象,对象中的键值对就是URL参数。所以在这个例子中,可以通过{ id }获取到id参数的值1。
你也可以在Route中使用路径参数:

jsx
<Route path="/users/:id" component={User} />

然后在User组件中使用useParams就可以获取这个路径参数了。
除了useParams外,在 class 组件中可以通过this.props.match.params获取URL参数:

jsx
function User({ match }) {
  const id = match.params.id;
  return <p>User ID: {id}</p> 
}

<Route path="/users/:id" component={User} />

match对象会包含URL参数信息,可以通过match.params访问URL参数。
所以总结有两种方式获取URL参数:

  • 函数组件:使用useParams hook
  • 类组件:通过this.props.match.params获取

在react中history模式中push和replace有什么区别?

push和replace都是用于导航到新页面的,但它们的行为略有不同:

push:
  • 将新页面添加到浏览历史中,它允许用户点击回退按钮回到前一个页面
  • 从当前页面跳转离开时,该页面会留存在浏览历史中
replace:
  • 用新的页面替换浏览历史中的当前页面
  • 从当前页面跳转离开时,当前页面将不留存在浏览历史中,无法回退到该页面
    举个例子:
    你有如下页面结构:
  • /home
  • /posts
  • /posts/1
  • /posts/2
    如果从/posts导航到/posts/1,使用:
  • history.push(‘/posts/1’)

那么浏览历史为:/home -> /posts -> /posts/1 ,可以回退到/posts页面

如果使用:

  • history.replace(‘/posts/1’)

那么浏览历史为:/home -> /posts/1 ,无法回退到/posts页面
所以总结:

  • 使用push可以返回到前一个页面
  • 使用replace导航到新页面,前一个页面无法回退到

React-Router怎么设置重定向?

在React Router中,可以通过Redirect组件设置重定向。
例如,从/old/path 重定向到 /new/path,可以这样写:

jsx
import { Redirect } from 'react-router-dom';

<Redirect from='/old/path' to='/new/path' />

你也可以在路由中添加Redirect:

jsx
<BrowserRouter>
  <Switch>
    <Route path="/old/path" render={() => <Redirect to="/new/path" />} />
  </Switch>
</BrowserRouter> 

此外,Redirect也支持其他一些属性:

  • push - 如果为true,重定向后会将新入栈history,可以点击后退返回到上一个页面。如果为false,history会替换为新路径。默认为true。
  • from - 需要重定向的现有路径。
  • to - 重定向的路径。
  • exact - 如果为true,当且仅当路径完全匹配时才会重定向。默认为false。
  • strict - 如果为false,在匹配路径末尾包含额外斜杠(/)时也将匹配。默认为true。

所以,在React Router中可以通过三种方式设置重定向:

  1. 使用组件
  2. 在路由中render
  3. 在代码中使用 history.push() 或 history.replace() 进行编程式导航

React Router的实现原理主要基于三个部分:

  1. History对象:用于管理浏览器历史记录和URL。React Router提供浏览器和内存两种History对象。浏览器History用于浏览器环境,内存History主要用于测试和SSR。
  2. Route对象:用于匹配URL路径,并返回一个RouteComponent。包含path、component、render、children等属性。
  3. Router对象:用于监听History对象的变化,然后匹配URL并渲染相应的RouteComponent。常用的有BrowserRouter和HashRouter。
    具体的工作原理是:
  4. 初始化History对象。在浏览器环境使用浏览器History,在Node环境使用内存History。
  5. 使用或的Router组件包裹根组件,这会给根组件传入history和match两个属性。
  6. 每当URL发生变化,Router就会调用History.listen()监听到URL变化。
  7. Router然后会遍历所有的或组件来寻找与新的URL匹配的第一个子。
  8. 一旦找到匹配的,Router就会使用该的component属性所对应的组件来渲染。
  9. 如果没有匹配的,Router则渲染null。
  10. 渲染出的组件会接收到Router传递的match、location和history props。
  11. 如果Route的render属性被定义,Router会调用它来返回要渲染的内容,而不是使用component。
  12. 嵌套的会继续匹配子路径,以渲染出更细致的UI。

所以,React Router的核心原理就是:
使用Router对象来监听URL变化
根据Route对象来匹配路径和返回响应组件
然后渲染该组件,同时传入location、match、history等props
以实现路由功能。
而历史管理则主要依靠History对象来实现。
所以Router、Route和History是React Router的三个核心部分,理解它们的作用和关系,就能掌握React Router的基本原理。

React的路由的优缺点?

React Router有以下优点:

  1. 与React无缝集成,在React项目中使用自然和方便。
  2. 支持React中的一切特性,如组件、Context等。
  3. 功能强大,支持嵌套路由、参数传递、路由守卫等。
  4. 简单易用,可以快速上手并开发单页应用。
  5. 支持HashRouter和BrowserRouter两种路由模式。
  6. 有活跃的社区支持和丰富的文档资料。

但是也有一些缺点:

  1. 需要配合服务端处理刷新时的404问题,增加了部署的难度。
  2. HashRouter有Hash值的显示问题,页面不够美观。BrowserRouter需要服务端配置支持,增加了复杂度。
  3. 嵌套路由太多时,Route匹配会变得比较耗费性能。
  4. 路由切换时,会重新渲染整个路由树,可能会有一定性能损耗。
  5. 学习成本略高,需要理解路由的各种工作原理和属性。
  6. 功能不像传统路由那么全面,在一些定制场景下可能会有限制。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值