mp.weixin.qq.com/s/0y-79NrBrKS-vta_iI5Tcg
一、依赖(Dependencies)在一般的SPA开发中,路由管理非常重要。作为反应技术系统的一部分,官方维护的反应路由器是首选的路由库。
应用Redux模式后,React-Router与Redux的合作出现了新的问题。需要带路线进店管理吗?如何将路线带入店铺进行管理?这些都是需要考虑的问题。我们后面会讨论第一个问题,为了解决上面提到的第二个问题,轻量级扩展库React-Router-Redux应运而生并被广泛使用。
另外需要注意的是,React-Router和React-Router-Redux长期以来是两个独立的库,但是在React-Router 4.x版本之后,React-Router-Redux已经成为React-Router 4 . x的一部分
本文不打算介绍这两种依赖库的具体用法(具体用法请参考官方文档和教程),主要阐述它们的实现方法和原理,并总结具体的实践方法和注意事项。在介绍主要内容之前,先简要介绍下两个库的功能:
React-Router React-Router 做的最重要的事就是将浏览器 URL 与程序联系起来(借助 history 库),它为 React 提供了声明式的路由系统,通过其提供的导航组件,我们能够方便地使用 URL 来控制状态的变化和组件的切换。React-Router-Redux 按照官方的说法,其实现了「deep integration of react-router and redux」,即 React-Router 与 Redux 的深度集成,它将路由完全纳入 store 中进行管理,使 store 成为了 URL(或者说是 history)的数据来源,也使我们能够通过 dispatch action 的方式来修改 URL。我们将在后文介绍它的实现原理。二、实践Redux架构中不必涉及路由状态。在一些简单的应用场景中,只需使用声明性组件(路由器、路由、链接等)就可以方便地实现URL导航。)由React-Router提供。在一些复杂的场景中,只要遵循React单向数据流模式和使用方法,也可以读取路由信息并触发变更,如下图所示。(有关用法,请参考反应路由器文档和教程。)
但是在这里,我们主要讨论将路由状态纳入Redux架构的情况。本部分的以下部分将分为两个部分:
手动管理,也就是不使用 React-Router-Redux;借助 React-Router-Redux 管理,这也是讨论的重点。2.1、手动管理 (Mannually)不需要其他库的帮助,一个简单的方法就是手动将路由状态带入商店进行管理,当URL发生变化时同步修改商店中的状态。
如上所示,在手动同步中,路由信息通过一组Redux机制存储在存储中。历史是数据源。通过监听历史,在URL状态改变时调度相应的动作(例如,type = LOCATION_CHANGE),通过添加的减压器将位置信息同步到店铺。这样,组件就可以获得商店中的位置状态信息,这也是目前react-reduce-starter-kit采用的方式。
这种相对原始的方式有一定的缺点:
没有将路由完全纳入 Redux 管理。路由不支持 time travel。history 实际也是 react-router 的路由数据来源,这就导致我们 store 中存储的 location 数据与 react-router 并不一定同步。(例如,这会导致文末讨论的重复渲染问题)2.2、使用 React-Router-Redux我们来讨论一下开头提出的第一个问题:是否需要将路线带入店内进行管理?虽然react-router-redux从4.x版本的react-router开始就成为其中的一部分,但官方对于是否应该在项目中使用提出了建议:
希望在项目中使用完全使用 store 管理路由数据希望使用 dispatch action 的方式进行导航(修改路由)希望调试时路由支持 time travel以上是使用React-Router-Redux的原理,当然在一定程度上也可以是决定将路由纳入店铺管理的原理。我想我们可以再补充两个:
项目抽象中,路由信息应该作为一种全局的状态管理有 Redux 强迫症2.2.1、原理通过图表了解React-Router-Redux的实现原理。
上图其实就是React-Router-Redux如何同步URL与状态的过程。在程序中,主要通过以下重要的API实现:
routerMiddleware 与 routerReducer routerMiddleware 与 routerReducer 的共同作用,让我们能够处理两种 action 类型:一种类型为 LOCATION_CHANGE,与手动管理过程中相同,它负责修改 store 存储;另一种类型为 CALL_HISTORY_METHOD,这类 action 一般会在组件内派发,它不负责 state 的修改,通过 routerMiddleware 后,会被转去调用 history 方法(如 push, replace 等),以修改 URL 状态。syncHistoryWithStore 顾名思义,这个方法就是处理路由与 store 中信息同步的重要方法。通过这个方法,我们能获得一个新的、增强版的 history 对象,这个对象重写了 history.listen 方法,原有的 history.listen 只负责 action (LOCATION_CHANGE) 的派发,新的 history.listen 则只监听 store 的变化(使用了 store.subscribe),所以当我们在程序内调用 history.listen 时,实际上是在监听 store 中的路由信息。2.2.2、实践:location as a prop在实际项目应用中,合理的实践模式如下。
也就是说,位置或子属性(如location.pathname等。)作为属性信息逐层传递给与路由信息有关的子组件,类似于react-router最初的使用方法,不同的是在改变URL时使用了调度动作。
三.建议3.1。谨慎使用state.routing
一般使用React-Router-Redux时,路由信息会以路由的形式体现出来。商店中的locationbeforetransition。在上面的实践中,我们没有直接从商店获得这个状态。其实官方不推荐。从名字上,作者已经明确提醒我们,这是一个不断变化的价值。
您不应该直接从Redux存储中读取位置状态。这是因为React Router异步运行(处理动态加载组件之类的事情),并且您的组件树可能还没有与您的Redux状态同步更新。您应该依赖React Router传递的道具,因为它们只有在处理完所有异步代码后才会更新。
不应直接从Redux存储读取路由状态。这是因为反应路由器的行为是异步的(例如,处理组件的动态加载等)。),所以你的组件树可能跟不上Redux状态的变化。您应该依赖React Router传递的属性,这样可以确保这些值在所有异步操作完成之前不会更新。
当路由中的值发生变化时,反应路由器可能尚未完成组件树的更新,使用此值可能会导致一些问题。因此,作者仍然建议我们通过传递位置属性来读取路由信息,以确保反应路由器完成处理。
3.2.仅传递必要的路由信息
只传递必要的信息,比如location.pathname和location.query.page,而不是传递整个位置。这样可以尽可能避免可能的重复渲染。
3.3.仅使用调度操作来修改路线
实际上,除了使用链路组件之外,在使用React-Router-Redux之后,还有许多方法可以修改路由信息,例如:
history.methodcontext.router.methoddispatch ROUTER-ACTION我还是建议只通过调度动作修改路由,这样更符合Redux流程,也方便解耦组件。在实际应用中,应该使用统一的动作创建器来创建用于修改路线的动作。
3.4.小心使用路由器高级组件(装饰器)
React-Router提供了withRouter高级组件,以便该组件可以访问路由状态信息(匹配、位置、历史),但是一旦引用的路由属性发生变化,它将触发重新呈现过程。如果使用不当,可能会导致组件的冗余重新渲染。
四、常见问题4.1、重渲染(重复渲染)问题
在使用React-Router和路由组件进行异步加载后,一个常见的问题是在组件切换时出现意外的重复呈现。在正常情况下(当代码未划分时),当反应路由器切换路由组件时,过程如下:
代码分割后,异步加载路由组件,过程如下:
因为组件A导入了位置或者它的相关属性,道具,位置的改变导致了道具的改变。此时由于组件B还没有加载成功,所以卸载之前组件A没有必要重新渲染。
通常,此问题是由于不正确使用已更改的路由信息引起的,如上面的状态路由信息,以及不同步的状态路由和反应路由器路由信息。解决方案:参考上述做法,使用Route组件注入的位置数据进行路由信息传输。
动词 (verb的缩写)引文
https://github.com/reactjs/react-router-reduxhttps://github.com/reactjs/react-router-tutorialhttps://github.com/ReactTraining/history[关于提交]
如果有原创的好文章投稿,请直接发消息到官方号。
1.《annually React 路由状态管理总结》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《annually React 路由状态管理总结》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/fangchan/1028775.html