Guide-2019-05-13-React Router 4.x官方文档翻译-原理

本指南的目的是解释使用React Router时的心智模型。我们将其称为“动态路由”,这与您可能更熟悉的“静态路由”完全不同。

静态路由

如果你使用过Rails, Express, Ember, Angular等框架,那么你已经使用过静态路由。
在这些框架中,在进行任何渲染之前,都将路由声明为应用初始化的一部分。
React Router v4版本之前也是静态的(大多数情况下)。
我们来看看如何在express中配置路由:

// Express Style routing:
app.get("/", handleIndex);
app.get("/invoices", handleInvoices);
app.get("/invoices/:id", handleInvoice);
app.get("/invoices/:id/edit", handleInvoiceEdit);

app.listen();

注意在app侦听之前是如何进行路由的声明的。

我们使用客户端路由的方式都是相似的。

Angular中,您可以预先声明您的路由,然后在渲染之前将它们导入顶级AppModule:

// Angular Style routing:
const appRoutes: Routes = [
  {
    path: "crisis-center",
    component: CrisisListComponent
  },
  {
    path: "hero/:id",
    component: HeroDetailComponent
  },
  {
    path: "heroes",
    component: HeroListComponent,
    data: { title: "Heroes List" }
  },
  {
    path: "",
    redirectTo: "/heroes",
    pathMatch: "full"
  },
  {
    path: "**",
    component: PageNotFoundComponent
  }
];

@NgModule({
  imports: [RouterModule.forRoot(appRoutes)]
})
export class AppModule {}

Ember有一个传统的routes.js文件,构建会读取并导入到应用程序中。这同样发生在你的app渲染之前。

// Ember Style Router:
Router.map(function() {
  this.route("about");
  this.route("contact");
  this.route("rentals", function() {
    this.route("show", { path: "/:rental_id" });
  });
});

export default Router;

尽管API不同,但它们都共享“静态路由”模型。 在v4版本之前,React路由器是由该模型引导出来的。要成功使用React Router,您需要忘记这一切!

背景(可不用看)

坦白说,我们对于v2版本的React Router感到非常沮丧。我们(Michael和Ryan)感觉受到API的限制,认识到虽然我们重新实现了React(生命周期等)的部分,但它与React给我们创建UI的心理模型不匹配。

在研讨会讨论如何应对之前,我们正走过酒店的走廊。我们互相问道:“如果我们使用我们在工作室教授的模式构建路由器会是什么样子?”

开发只需要几个小时,我们就有一个概念验证,我们知道这是我们想要的路由的未来。我们最终得到的API并不是React的“外部”,这是一个由React的其余部分组成或自然落实到位的API。我们认为你会喜欢它。

动态路由

当我们说动态路由时,我们指的是在您的应用渲染时发生的路由,而不是在正在运行的应用之外的配置或约定中。这意味着几乎所有东西都是React Router中的一个组件。这是对API的60秒评论,看看它是如何工作的:
首先,为自己定位的环境抓住自己的路由器组件,并将其呈现在应用的顶部。

// react-native
import { NativeRouter } from "react-router-native";

// react-dom (what we'll use here)
import { BrowserRouter } from "react-router-dom";

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  el
);

其次,使用<Link>组件导航到新地址。

const App = () => (
  <div>
    <nav>
      <Link to="/dashboard">Dashboard</Link>
    </nav>
  </div>
);

最后,当用户访问地址/dashboard时,使用<Route>渲染出某些内容(这里是Dashboard组件)。

const App = () => (
  <div>
    <nav>
      <Link to="/dashboard">Dashboard</Link>
    </nav>
    <div>
      <Route path="/dashboard" component={Dashboard} />
    </div>
  </div>
);

<Route>将会渲染<Dashboard {...props}/>,这里的props是路由的特殊对象{match, location, history}。如果用户不在/dashboard这个路径,那么<Route>这里就会渲染null, 也就是什么都不显示。

这就是它的全部内容。

嵌套路由

很多路由器都有一些“嵌套路由”的概念。如果您在v4之前使用过React Router的版本,那么您也知道它也是如此!当您从静态路由配置移动到动态渲染路由时,如何“嵌套路由”?那么,你是如何嵌套一个‘div’的?
路由器没有“嵌套”API?<Route>只是一个组件,就像div一样。因此,为了嵌套路由或div,你只需像使用div一样使用<Route>。

const App = () => (
  <BrowserRouter>
    {/* here's a div */}
    <div>
      {/* here's a Route */}
      <Route path="/tacos" component={Tacos} />
    </div>
  </BrowserRouter>
);

// when the url matches `/tacos` this component renders
const Tacos = ({ match }) => (
  // here's a nested div
  <div>
    {/* here's a nested Route,
        match.url helps us make a relative path */}
    <Route path={match.url + "/carnitas"} component={Carnitas} />
  </div>
);

响应路由

假如用户导航到/invoices时,您的应用要适应于不同的屏幕尺寸,它们都具有较窄的视口,那您只需向其显示发票列表和以及不同发票内容的链接。


image.png

在更大的屏幕上,我们想要显示一个主 - 详细视图,其中导航位于左侧,在右侧显示相应的导航的内容。


image.png

以下代码:
当用户将手机从纵向旋转到横向时,此代码会自动将其重定向到/invoices/dashboar。该组有效路由根据用户手中的移动设备的动态特性而改变。
const App = () => (
  <AppLayout>
    <Route path="/invoices" component={Invoices} />
  </AppLayout>
);

const Invoices = () => (
  <Layout>
    {/* always show the nav */}
    <InvoicesNav />

    <Media query={PRETTY_SMALL}>
      {screenIsSmall =>
        screenIsSmall ? (
          // small screen has no redirect
          <Switch>
            <Route exact path="/invoices/dashboard" component={Dashboard} />
            <Route path="/invoices/:id" component={Invoice} />
          </Switch>
        ) : (
          // large screen does!
          <Switch>
            <Route exact path="/invoices/dashboard" component={Dashboard} />
            <Route path="/invoices/:id" component={Invoice} />
            <Redirect from="/invoices" to="/invoices/dashboard" />
          </Switch>
        )
      }
    </Media>
  </Layout>
);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容