React 入門第五步:組件布局小案例
回憶一下前四篇:
我們結合前面學習的內容,做一個界面布局的小案例,案例最終呈現(xiàn)的效果如下:

基本布局
CSS 樣式已經提前寫好了,放在根路徑下,起名為 style.css,具體代碼如下:
html, body { height: 100%; }body { margin: 0; padding: 0; }.header, .footer {width: 100%; height: 80px; position: absolute; left: 0;line-height: 80px; text-align: center; font-size: 18px;color: #fff;}.header { background-color: skyblue; top: 0; }.footer { background-color: purple; bottom: 0; }.main {width: 100%; position: absolute; top: 80px; bottom: 80px;padding: 20px 0; text-align: center; background: khaki;}
我們創(chuàng)建好對應的子組件,分別為 src\Components\Header.js、src\Components\Home.js、src\Components\Footer.js。
在 \src\App.js 中引入上面的三個子組件及樣式文件:
import React, { Component } from 'react'import Header from './Components/Header'import Home from './Components/Home'import Footer from './Components/Footer'import './style.css'export class App extends Component {render() {return (<><Header></Header><Home></Home><Footer></Footer></>)}}export default App
然后在子組件中,分別寫好初始代碼,因為已經有了對應的樣式代碼,因此在子組件中直接使用即可:
// src\Components\Header.jsimport React from 'react'function Header() {return (<><div className={'header'}>Header</div></>)}export default Header// =================================================// src\Components\Home.jsimport React from 'react'function Home() {return (<><div className={'main'}>Home</div></>)}export default Home// =================================================// src\Components\Footer.jsimport React from 'react'function Footer() {return (<><div className={'footer'}>Footer</div></>)}export default Footer
基礎代碼實現(xiàn)之后,我們就能看到對應的效果了。但是,按照正常的編碼邏輯,header 和 footer 應該屬于公共部分,中間部分無論展示什么內容,頭和尾都是需要展示的。
集成公共組件
我們需要將 Header 和 Footer 作為公共組件使用,需要添加一個src\Components\Layout.js 組件,Layout 組件的作用就是將 header與 footer 顯示出來,同時把中間的 main 內容空出來,將來我們傳入什么樣的 JSX ,那么 main 里就顯示什么樣的 DOM。
在 Layout.js 中,引入 Header 與 Footer 組件并應用在 JSX 中,然后利用 JSX 傳參,展示主體內容。前面我們已經學習過,這里使用的是函數(shù)組件,只需要在函數(shù)中使用形參獲取 Props ,然后在展示主體內容的地方獲取 {props.children} 就可以了:
import React from 'react'import Header from './Header'import Footer from './Footer'function Layout(props) {return (<><Header /><div className="main">{props.children}</div><Footer /></>)}export default Layout
公共組件完成后,我們想展示那個主體組件的內容,就在那個組件中引入 Layout ,然后將主體內容以傳遞 jsx 的方式傳入就可以了,最后再在 App 中,引入主體組件進行展示,具體代碼如下:
// Home.jsimport React from 'react'import Layout from './Layout'function Home() {return (<Layout><div>Home</div></Layout>)}export default Home// ====================================// List.jsimport React from 'react'import Layout from './Layout'function List() {return (<Layout><div className="main">list</div></Layout>)}export default List// ====================================// App.jsimport React, { Component } from 'react'import Home from './Components/Home'import List from './Components/List'import './style.css'export class App extends Component {render() {return (<><Home /><List /></>)}}export default App
總的來說,就是利用了向組件傳遞 JSX 的特性實現(xiàn)的。
最后,做個小總結,從接觸組件這個概念,到組件間的傳遞,我們學習了很多內容,也深刻的體會了 JSX 就是 JS 這個概念。
而在組件間數(shù)據(jù)傳遞部分,Props 是核心關鍵點。
但是,你可能還不知道,Props 有一個非常重要的特性:只讀,意思就是我們在組件中獲取到的 Props 數(shù)據(jù),你只能用,而不能改。
官方手冊的原話是:
組件無論是使用函數(shù)聲明還是通過class 聲明,都絕不能修改自身的 Props……
React 非常靈活,但它也有一個嚴格的規(guī)則:所有 React 組件都必須像純函數(shù)一樣保護它們的 props 不被更改。
這里提到了一個 函數(shù)式編程 中的 純函數(shù) 概念,我簡單解釋一下什么是純函數(shù):“函數(shù)不會在函數(shù)體中修改入?yún)?,且在多次調用下,相同的入?yún)⑹冀K返回相同的結果。”
其實,從這里可以看出,React 團隊希望組件本身是具有純函數(shù)特性的,因此,Props 就需要設置為只讀的,不能在組件中被修改。
但是問題是,我們界面展示的內容是需要根據(jù)數(shù)據(jù)改變而改變的,而 React 設計的核心理念中有非常重要的一點就是 數(shù)據(jù)驅動 UI。
看到這里,你一定會覺得 React 在自相矛盾,一邊傳入的 Props 數(shù)據(jù)是只讀不可改變的,一邊又依靠數(shù)據(jù)的改變而驅動 DOM 的改變。
真的是這樣嗎?
當然不是,數(shù)據(jù)驅動 UI 中的數(shù)據(jù)另有其人,它稱之為 “state”,也叫狀態(tài),作用就是在不違反上述規(guī)則的情況下,state 允許 React 組件隨用戶操作、網絡響應或者其他變化而動態(tài)更改輸出的內容。
推薦閱讀:
恭喜你又在前端道路上進步了一點點。
點個“在看”和“贊”吧!
