Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React Router Dom 及其工作原理 #114

Open
yangtao2o opened this issue Apr 14, 2020 · 0 comments
Open

React Router Dom 及其工作原理 #114

yangtao2o opened this issue Apr 14, 2020 · 0 comments

Comments

@yangtao2o
Copy link
Owner

yangtao2o commented Apr 14, 2020

React Router

Router 会创建一个 history 对象,history 用来跟踪 URL,当 URL 发生变化时,Router 的后代组件会重新渲染。React Router 中提供的其他组件可以通过 context 获取 history 对象,所以,React Router 中的其他组件必须作为 Router 组件的后代组件使用。但 Router 中只能有唯一的一个子元素。

基本组件

React Router 中有三类组件:

  • router 组件(BrowserRouter,HashRouter)
  • route matching 组件(Route,Switch)
  • navigation 组件(Link)

使用 react-router-dom 之前,我们需要在工程路径下安装这个包

npm install react-router-dom

安装完成后,上面所列出的这些组件,我们可以通过 react-router-dom 得到。

import { BrowserRouter, Route, Link } from "react-router-dom";

Route Rendering Props

<Route> 匹配时所显示的组件,有三种写法:

  • component
  • render
  • children
<Route path="/user/:username" component={User} />;
// convenient inline rendering
<Route path="/foo" render={(props) => (
  <Foo {...props} data={exactProps} />
)} />
<Route path="/foo" children={(props) => (
  <div className={props.match ? 'active' : ''}>
    <Foo />
  </div>
)} />

function User({ match }) {
  return <h1>Hello {match.params.username}!</h1>;
}

Navigation

  • Link
  • Navlink
  • Redirect
<Link to="/">Home</Link>
// <a href='/'>Home</a>

// location = { pathname: '/react' }
<NavLink to="/react" activeClassName="hurray">
  React
</NavLink>
// <a href='/react' className='hurray'>React</a>

<Route exact path="/" render={() => (
  loggedIn ? (
    <Redirect to="/dashboard"/>
  ) : (
    <PublicHomePage/>
  )
)}/>

withRoute

不是通过 Route 渲染出来的组件没有 match、location、history 三个属性,但是又想要使用这三个属性,那该怎么办呢,所以可以在外面套一层 Route 组件,从而得到这三个属性,这种做法叫高阶组件。

前端路由原理

hash

https://www.word.com#search

此外,hash 也存在下面几个特性:

URL 中 hash 值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash 部分不会被发送。
hash 值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash 的切换。

我们可以使用 hashchange 事件来监听 hash 的变化。

我们可以通过两种方式触发 hash 变化,一种是通过 a 标签,并设置 href 属性,当用户点击这个标签后,URL 就会发生改变,也就会触发 hashchange 事件了:

<a href="#search">search</a>

复制代码还有一种方式就是直接使用 JavaScript来对 loaction.hash 进行赋值,从而改变 URL,触发 hashchange 事件:

location.hash="#search"

history

window.history.pushState(null, null, path);
window.history.replaceState(null, null, path);

history 存在下面几个特性:

  • pushState 和 repalceState 的标题(title):一般浏览器会忽略,最好传入 null ;

  • 我们可以使用 popstate  事件来监听 url 的变化;

  • history.pushState() 或 history.replaceState() 不会触发 popstate 事件,这时我们需要手动触发页面渲染;

  • 深度剖析:前端路由原理

参考资料

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant