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中可以通过三种方式设置重定向:
- 使用组件
- 在路由中render
- 在代码中使用 history.push() 或 history.replace() 进行编程式导航
React Router的实现原理主要基于三个部分:
- History对象:用于管理浏览器历史记录和URL。React Router提供浏览器和内存两种History对象。浏览器History用于浏览器环境,内存History主要用于测试和SSR。
- Route对象:用于匹配URL路径,并返回一个RouteComponent。包含path、component、render、children等属性。
- Router对象:用于监听History对象的变化,然后匹配URL并渲染相应的RouteComponent。常用的有BrowserRouter和HashRouter。
具体的工作原理是: - 初始化History对象。在浏览器环境使用浏览器History,在Node环境使用内存History。
- 使用或的Router组件包裹根组件,这会给根组件传入history和match两个属性。
- 每当URL发生变化,Router就会调用History.listen()监听到URL变化。
- Router然后会遍历所有的或组件来寻找与新的URL匹配的第一个子。
- 一旦找到匹配的,Router就会使用该的component属性所对应的组件来渲染。
- 如果没有匹配的,Router则渲染null。
- 渲染出的组件会接收到Router传递的match、location和history props。
- 如果Route的render属性被定义,Router会调用它来返回要渲染的内容,而不是使用component。
- 嵌套的会继续匹配子路径,以渲染出更细致的UI。
所以,React Router的核心原理就是:
使用Router对象来监听URL变化
根据Route对象来匹配路径和返回响应组件
然后渲染该组件,同时传入location、match、history等props
以实现路由功能。
而历史管理则主要依靠History对象来实现。
所以Router、Route和History是React Router的三个核心部分,理解它们的作用和关系,就能掌握React Router的基本原理。
React的路由的优缺点?
React Router有以下优点:
- 与React无缝集成,在React项目中使用自然和方便。
- 支持React中的一切特性,如组件、Context等。
- 功能强大,支持嵌套路由、参数传递、路由守卫等。
- 简单易用,可以快速上手并开发单页应用。
- 支持HashRouter和BrowserRouter两种路由模式。
- 有活跃的社区支持和丰富的文档资料。
但是也有一些缺点:
- 需要配合服务端处理刷新时的404问题,增加了部署的难度。
- HashRouter有Hash值的显示问题,页面不够美观。BrowserRouter需要服务端配置支持,增加了复杂度。
- 嵌套路由太多时,Route匹配会变得比较耗费性能。
- 路由切换时,会重新渲染整个路由树,可能会有一定性能损耗。
- 学习成本略高,需要理解路由的各种工作原理和属性。
- 功能不像传统路由那么全面,在一些定制场景下可能会有限制。