如何使用 Backbone Router 和 React States
介绍
BackboneJS 主要是一个 JavaScript MVC 框架,而 React 则将自己定位为一个 JavaScript UI 库。BackboneJS 为您的代码库提供了有组织的结构和可以与数据通信的明确模型。在 BackboneJS 中使用 React 作为视图库将提高您的应用程序的性能,因为 React 使用虚拟 DOM。
在本指南中,您将学习如何将 React 组件与 Backbone 路由器一起使用。
BackboneJS 中现有视图的问题
Backbone 视图是负责 UI 和布局的模板模型。Backbone 视图在功能上与 React 组件相同,但工作方式和性能有所不同。在使用 Backbone 视图时,您应该注意一些问题。本指南不会解决这些问题,但会提供使用 React 组件的替代方法。
不可重用的视图
Backbone 视图的复用难度比 React 组件大得多。它们有时毫无用处,而且通常依赖于 Underscore 或 Mustache 等渲染引擎,这可能会限制功能。
更新 DOM 很困难
BackboneJS 中的典型模式是监听各种 DOM 事件(单击、更改等),并在触发时使用 jQuery 手动刷新 DOM 以删除和附加不同的元素。
性能问题
就性能而言,Backbone 视图无法在不重新渲染整个 DOM 的情况下更新 DOM 部分,这可能会非常昂贵。React 通过使用虚拟 DOM 并仅更新需要重新渲染的 DOM 部分来克服这个问题。
骨干路由器
主干路由器用于路由 Web 应用程序的 URL。以前,哈希片段 ( #page ) 用于路由 URL,但随着 History API 的引入,现在可以使用标准 URL ( /page ) 进行路由。
Backbone 路由器并不完全符合 MVC 路由器的传统定义,尽管 Backbone 路由器对于任何需要 URL 路由功能的应用程序来说仍然很方便。在传统的 MVC 框架中,路由发生在服务器端,而在 Backbone 中,路由由浏览器在客户端处理。
指定的路由器应始终包含至少一个路由和一个将特定路由映射到其对应视图的函数。在下面的示例中,您可以看到如何使用Backbone.Router定义路由。
import Backbone from "backbone";
const Router = Backbone.Router.extend({
routes: {
foo: "foo",
bar: "bar"
},
foo: function () {
// action to map foo URL to the specific view
},
bar: function () {
// action to map bar URL to the specific view
}
});
new Router();
extend ()方法创建一个自定义路由类。它定义了当某些 URL 部分匹配时触发的操作函数,并提供将路由与特定操作配对的路由哈希。
routes对象为路由器定义一个键值对,其中键是 URL 片段,值是其路由或操作函数。
您还可以通过定义参数部分(例如:param )将路由参数传递到路由操作中,该参数部分与斜杠之间的单个 URL 组件匹配。可以通过将其括在括号中使其成为可选项:(/:param)。
const Router = Backbone.Router.extend({
routes: {
"foo/:id": "foo"
},
foo: function (id) {
console.log("Route param : ", id);
}
});
实例化路由器并正确设置所有路由后,调用Backbone.history.start()开始监视 URL 更改或hashchange事件并分派路由操作。要使用常规 URL 结构而不是哈希 URL,您可以将pushState选项传递给start()方法Backbone.history.start({ pushState: true })。
在路由操作中渲染 React 组件
在本节中,您将学习如何从路由操作函数中呈现 React 组件。
通过定义一个新的路由器类来开始。
import { Router, history } from "backbone";
const AppRouter = Router.extend({
routes: {
"": "init",
"profile/:id": "profile",
"search/:term": "search"
},
init: () => {
console.log("This is the first page");
},
profile: id => {
console.log("This is the profile page", id);
},
search: term => {
console.log("The user is searching for " + term);
}
});
new AppRouter();
history.start({ pushState: true });
如果您在导航到 URL 时看到控制台日志,则表示路由已完美设置。
接下来,为每个路线操作创建 React 组件。
import React from "react";
const IndexPage = () => (
<div>
<h1>Hey, this is the Home Page.</h1>
</div>
);
const ProfilePage = props => (
<div>
<h1>Thanks for visiting the Profile Page</h1>
<h2>The Profile ID is {props.profileId}</h2>
</div>
);
const SearchPage = props => (
<div>
<h1>Searching for {props.searchTerm}...</h1>
</div>
);
要在 DOM 元素中渲染组件,请使用ReactDOM.render()方法,就像在任何其他 React 应用程序中一样。要试用它,请从init()函数渲染<IndexPage />组件。
import ReactDOM from "react-dom";
const rootElement = document.getElementById("root");
routes: {
// ...
}
init: () => {
ReactDOM.render(<IndexPage />, rootElement);
};
//
现在,如果你访问索引 URL,你应该会看到<IndexPage />组件的内容。无需一次又一次地调用ReactDOM.render(),只需创建一个辅助函数来渲染组件。
把所有这些放在一起,并将路由参数作为 props 传递给相应的页面组件。
// ...
const rootElement = document.getElementById("root");
const renderView = View => ReactDOM.render(View, rootElement);
const AppRouter = Router.extend({
routes: {
"": "init",
"profile/:id": "profile",
"search/:term": "search"
},
init: () => renderView(<IndexPage />),
profile: id => renderView(<ProfilePage profileId={id} />),
search: term => renderView(<SearchPage searchTerm={term} />)
});
// ...
完整源代码
下面您可以找到完整的代码供您参考。
import React from "react";
import ReactDOM from "react-dom";
import { Router, history } from "backbone";
const rootElement = document.getElementById("root");
const renderView = View => ReactDOM.render(View, rootElement);
const IndexPage = () => (
<div>
<h1>Hey, this is the Home Page.</h1>
</div>
);
const ProfilePage = props => (
<div>
<h1>Thanks for visiting the Profile Page</h1>
<h2>The Profile ID is {props.profileId}</h2>
</div>
);
const SearchPage = props => (
<div>
<h1>Searching for {props.searchTerm}...</h1>
</div>
);
const AppRouter = Router.extend({
routes: {
"": "init",
"profile/:id": "profile",
"search/:term": "search"
},
init: () => renderView(<IndexPage />),
profile: id => renderView(<ProfilePage profileId={id} />),
search: term => renderView(<SearchPage searchTerm={term} />)
});
new AppRouter();
history.start({ pushState: true });
结论
主干路由只是可以处理来自 URL 的传入路由值并为该路由调用特定操作的对象。
本指南的一个重要结论是,您应该灵活地在应用程序代码库中实现两个或更多 JavaScript 堆栈。这样做将帮助您大致了解不同库如何相互协作以及如何克服每个库的缺点。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~