1

最近使用react router 遇到一个问题:当对某个路由添加参数的时候/list/:app 这列路由,点击这个路由以后再点击其他路由,location地址就追加到后面,问不是replace.

/list/:app => /list/appName

切换到/info 就变成了/list/appName/info

最后通过定位,发觉是在Link的时候对Link的to没有添加绝对地址的原因。

<Link to="list/appName" /> 要修改为<Link to="/list/appName" />

在定位这个问题的时候,看了一下各个部分的源代码,下面对react router v4做一个简单的介绍。

分别从route, history, location, match 做介绍。

route

1、route 三种render方式:component, render, function
2、route的props: match, location, history
3、router的path当不指定path的时候就会一直匹配

route path 匹配写法:

  <Route path='tasks_list/:app/:jobId' component={component} />

如果params 是可选的写法:

<Route path='tasks_list/:app/:jobId?' component={component} />

history

history 是一个路由中最重要的部分,一般来说用户只有两种方式会更新当前 URL。一种是用户点击了某个锚标签或者直接操作 history 对象的 replace/push 方法;另一种是用户点击前进/后退按钮。无论哪一种方式都要求我们的路由系统能够实时监听 URL 的变化,并且在 URL 发生变化时及时地做出响应,渲染出正确的页面。我们首先来考虑下如何处理用户点击前进/后退按钮。React Router 使用 History 的 .listen 方法来监听当前 URL 的变化,其本质上还是直接监听 HTML5 的 popstate 事件。
当监听到 popstate 事件被触发时,我们会调用 forceUpdate 函数来强制进行重渲染。总结而言,无论我们在系统中设置了多少的路由组件,它们都会独立地监听 popstate 事件并且相应地执行重渲染操作。接下来我们继续讨论 matchPath 这个 Route 组件中至关重要的函数,它负责决定当前路由组件的 path 参数是否与当前 URL 相一致。

react router 的history 是调用了ReactTraining的history
react router 的history有以下属性与方法:

  1. length - (number) The number of entries in the history stack
  2. action - (string) The current action (PUSH, REPLACE, or POP)
  3. location - (object) The current location. May have the following properties:

1) pathname - (string) The path of the URL
2)search - (string) The URL query string
3)hash - (string) The URL hash fragment
4)state - (string) location-specific state that was provided to e.g. push(path, state) when this location was pushed onto the stack. Only available in browser and memory history.

 1)push(path, [state]) - (function) Pushes a new entry onto the history stack
2)replace(path, [state]) - (function) Replaces the current entry on the history stack    
3)go(n) - (function) Moves the pointer in the history stack by n entries
4)goBack() - (function) Equivalent to go(-1)    
5)goForward() - (function) Equivalent to go(1)
6)block(prompt) - (function) Prevents navigation (see the history docs)

location

location指定当前的app在哪儿
Route component as this.props.location
Route render as ({ location }) => ()
Route children as ({ location }) => ()
withRouter as this.props.location
比如上面遇到的问题,就是location的问题,最后定位到是createLocation的方法出的问题。

match

有了location, 然后有了route, match包含的信息就是 <Route path>如何匹配当前的location

  1. params - (object) Key/value pairs parsed from the URL corresponding to the dynamic segments of the path
  2. isExact - (boolean) true if the entire URL was matched (no trailing characters)
  3. path - (string) The path pattern used to match. Useful for building nested <Route>s
  4. url - (string) The matched portion of the URL. Useful for building nested <Link>

Redirect

这个组件并没有真实地进行界面渲染,而是仅仅进行了简单的跳转操作


小渝人儿
1.1k 声望850 粉丝

前端工程师