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

    xiaoxiao2021-03-26  22

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

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

    目标

    细心的同学应该能发现:每一个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)

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

    转载请注明原文地址: https://ju.6miu.com/read-660041.html

    最新回复(0)