架構介紹
在 Next.js 架構中 pages 目錄(File-System) 即 Route,pages 底下的檔案就是一個Router Container,可以用Share Component 來組成 Container,放在 pages 以外的自定義目錄大概會長下面這個樣子,除了 pages 與 statc 是約定目錄其他可以自定義
/pages
/components/layout
/components/更多元件..
/static
1.傳入children的方式來製作layout
利用 React 在 Tag 之中會把內容當作 children,並使用props參數,傳入元件之中以下方為例
import Layout from '../components/layout'
export default () => (
<Layout>
<div> 製作一個具有Layout的網站吧 </div>
</Layout>
)
在下面layout.js 可以看到在 StateLess Function 傳入 children 參數,Render 中的 { children } 就是上面傳入包在 Layout TAG 中的內容( 製作一個具有Layout的網站吧 ) ,利用這樣傳資料的方式就可以製作一個共用的 Layout 在把每一頁的內容都加上 Layout Tag 就完成了
這邊用 Head 是因為 Layout 無法改變 Document 的 Meta或是Title Tag 只能修改在 React Render Dom 節點內容
,所以 Next.js 提供了Head供可以修改 Document 的內容,使用時候記得引入 import Head from 'next/head'
layout.js
import Link from 'next/link'
import Head from 'next/head'
export default ({ children, title = 'This is the default title' }) => (
<div>
<Head>
<title>{ title }</title>
<meta charSet='utf-8' />
<meta name='viewport' content='initial-scale=1.0, width=device-width' />
</Head>
<header>
<nav>
<Link href='/'><a>家目錄</a></Link> |
<Link href='/about'><a>關於我</a></Link> |
<Link href='/contact'><a>與我聯絡</a></Link>
</nav>
</header>
{ children }
<footer>
{'我是底部'}
</footer>
</div>
)
2.利用HIGH ORDER COMPONENT HOC來製作Layout
HOC 在 React 中最常看到的範例就是 Redux 的 connect ,HOC 可以把目前的物件 當作 Function 的參數傳入 ,然後在 Function 之中可以把目前傳入的物件經過加工 props 或是 states 或是改變 Render 形態 ,讓原來的物件可以被擴充或是加工,範例如下 有各PageA 利用 HOC 包起來就具備有 Layout 的效果,這個比起 children 方式可以有更多彈性
class PageA extends Component{
render(){
return "這裡是PageA"
}
}
export default Layout(PageA)
這時候的Layout.js會是這樣
export default (PageA)=>{
return class AnyPage exnteds Component{
render(){
return (<div><header/><PageA/><footer/></div>)
}
}
}
在ES7 新的語法之中有 Decorator 裝飾子可以使用可以使用下面 @layout 置於class上方比較好閱讀
( decorator 使用時 是屬於新功能 https://babeljs.io/docs/plugins/transform-decorators/ 設定參考)這樣等同於 HOC 的寫法
@layout
class PageA extends Component{
render(){
return "這裡是PageA"
}
}
以上是常用在製作 Layout 的兩個方法
心得
在 Next.js 製作 Layout 與一般 React 並無差異 要注意的是 Head 的使用 如果需要更多彈性可以考慮使用 HOC 來製作 Layout 層