IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [译]基于 React Router 4 的可复用 Layout 组件

    justjavac发表于 2017-04-07 13:52:20
    love 0

    本文翻译自:Reusing layouts in React Router v4

    在 React Router V4 应用中,希望在每个路由上呈现一些默认的组件,比如页眉和页脚:

    <div className="App">
      <div className="Header">
        Page Header
      </div>
      <div className="Content">
        {content that changes}
      </div>
      <div className="Footer">
        Page Footer
      </div>
    </div>

    在最新版本的 React Router V4 中可以很容易实现这一点,通过为特定的用例创建子布局。

    创建默认布局

    我们把每个页面都使用的布局作为默认布局。当页面路由和地址栏匹配的时候,React router 会调用 render 属性的函数:

    // 调用组件的常规方式
    <Route path="/" component={SomeComponent} />
    
    // 使用 render 属性可以最组件做一些自定义操作
    <Route path="/" render={matchProps => <SomeComponent {...matchProps} />} />

    这是非常有用的,因为我们可以把这些组件放到 <Route /> 中,然后控制哪些组件应该被渲染,同时把 Route 的属性传递给子组件:

    const DefaultLayout = ({component: Component, ...rest}) => {
      return (
        <Route {...rest} render={matchProps => (
          <div className="DefaultLayout">
            <div className="Header">Header</div>
              <Component {...matchProps} />
            <div className="Footer">Footer</div>
          </div>
        )} />
      )
    };
    <DefaultLayout path="/" component={SomeComponent} />

    rest 参数包含了需要传递给 DefaultLayout 的除了 component 以外的所有属性,所以我们可以把这些属性从 Route 转发到底层组件。

    通过向 Route 组件提供 render 属性,我们可以控制 component 属性的渲染。在这种情况下,我们将其包含在包含页眉和页脚的 HTML 中,但这可能只是把其他组件做了简单的分组。matchProps 是 Route 渲染时的另一个属性。

    一个非常重要的注意点是把 component 组件重新命名为 Component,因为它会影响 JSX 如何转换我们的代码:

    <component />
    // 转换为
    React.createElement("component", null); // 不是我们需要的
    
    <Component />
    // 转换为
    React.createElement(Component, null); // 现在,这是一个 React 组件

    阅读 facebook 官方文档 "用户自定义组件必须是大写字母开头" 获取更多信息。

    扩展默认布局

    我们的默认布局已经包含了在每个页面上的需要共享的组件,可能有时候我们还要为某个视图添加某些特定组件,例如博客的帖子。解决这个问题的一个方法是创建 DefaultLayout 然后只为那些新页面添加特定组件:

    const PostLayout = ({component: Component, ...rest}) => {
      return (
        <DefaultLayout {...rest} component={matchProps => (
          <div className="Post">
            <div className="Post-content">
              <Component {...matchProps} />
            </div>
            <div className="Post-aside">
              <SomeSideBar />
            </div>
          </div>
        )} />
      );
    };
    <PostLayout path="/posts/:post" component={PostComponent} />

    唯一的区别是将函数传递给 component 属性而不是 render 属性。您可以根据需要自由扩展布局。

    仅此而已

    短小精悍。

    React Router 的新版本专注于使用 React 组件模型,而这些组件可以非常简单的组合在一起。

    查看这个 GitHub issue,可以看看对于使用不同的默认布局的讨论。

    React Router V4 文档中文翻译 正在进行中。。。



沪ICP备19023445号-2号
友情链接