首页 > 网站 > WEB开发 > 正文

【React全家桶入门之七】提取布局组件

2024-04-27 15:05:51
字体:
来源:转载
供稿:网友

是时候来优化一下我们的代码了。

前面的文章提到过:重复代码是混乱的根源!,本篇文章我们来继续消灭重复代码。

目标

细心的同学应该能发现:每一个Page组件/src/pages下的组件)的render方法都拥有相似的jsx结构,比如:

render () { return ( <div> <header> <h1>...</h1> </header> <main> ... </main> </div> );}

每一个页面都包含一个页面的标题(header标签和h1标签),并且页面的主要部分都被放在了一个main标签中。

现在很多网站的设计都是如此:大部分页面都有相似的header和footer,不同的是中间部分的内容。

既然是这些部分都是相似的,那么在每一个地方都重复写一遍就显得太没水平了,stupid!

怎么用一份代码来渲染这些相同的地方,并且也能够满足不同的页面之间一些差异化的配置呢(如本文中各页面标题不同)?

传统的MVC Web应用可以通过模板引擎的模板页(layout)来达到这样的效果。

使用React,我们可以使用布局组件来解决这个问题。

布局组件

新建/src/layouts目录用来存放布局组件,新建HomeLayout.js文件:

import React from 'react';class HomeLayout extends React.Component { render () { const {title, children} = this.PRops; return ( <div> <header> <h1>{title}</h1> </header> <main> {children} </main> </div> ); }}export default HomeLayout;

我们把每个页面中通用的部分提取到了HomeLayout组件中,在HomeLayout中使用props.title来维护页面的标题文本。

使用props.children来渲染每个页面特有的内容部分。

现在我们可以这样来渲染HomePage:

<HomeLayout title="Welcome"> <Link to="/user/list">用户列表</Link> <br/> <Link to="/user/add">添加用户</Link></HomeLayout>

HomeLayout里面的内容会作为HomeLayout的props.children渲染到最终的页面上。

重构页面组件

主页

...import HomeLayout from '../layouts/HomeLayout';class Home extends React.Component { render () { return ( <HomeLayout title="Welcome"> <Link to="/user/list">用户列表</Link> <br/> <Link to="/user/add">添加用户</Link> </HomeLayout> ); }}...

用户添加页面

...import HomeLayout from '../layouts/HomeLayout';class UserAdd extends React.Component { handleSubmit (e) { ... } render () { ... return ( <HomeLayout title="添加用户"> <form onSubmit={(e) => this.handleSubmit(e)}> ... </form> </HomeLayout> ); }}...

用户列表页面

...import HomeLayout from '../layouts/HomeLayout';class UserList extends React.Component { constructor (props) { ... } componentWillMount () { ... } render () { ... return ( <HomeLayout title="用户列表"> <table> ... </table> </HomeLayout> ); }}...

总结

现在我们已经把3个页面组件的重复部分使用HomeLayout来替代了,是不是觉得代码又变得干净了很多呢?

请像洁癖一样对待自己的代码。

你以为页面重构就到此为止了吗?

现在每一个页面都要先import HomeLayout组件,然后将页面内容使用HomeLayout组件包裹起来。

如果你足够“洁癖”,这里也应该成为你“清扫”的目标。

怎么做?

// /src/index.js...ReactDOM.render(( <Router history={hashHistory}> <Route path="/" component={HomeLayout> <Route path="/" component={HomePage}/> <Route path="/user/add" component={UserAddPage}/> <Route path="/user/list" component={UserListPage}/> </Route> </Router>), document.getElementById('app'));

我们可以给每个需要使用HomeLayout布局的页面路由添加一个component为HomeLayout的父路由,其效果等同于:

当url为”/”:

<HomeLayout> <HomePage/></HomeLayout>

当url为”/user/add”:

<HomeLayout> <UserAddPage/></HomeLayout>

当url为”/user/list”:

<HomeLayout> <UserListPage/></HomeLayout>

HomeLayout将会根据当前的url从props.children接收到相应的组件内容。

这样做可以解除每个页面与HomeLayout之间的耦合,但也有一些问题:

title怎么办?(使用react context api)有的页面组件需要添加一个额外的根节点(如/src/pages/Home.js)

这里不再进行进一步的讲解,自己动手试试?


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表