函數(shù)是面向過程的漠魏,函數(shù)的調用不需要主體澳厢,而方法是屬于對象的鸦采,調用方法需要一個主體-即對象篙骡。
npm install -g create-react-app
創(chuàng)建react項目(具體看react-commend) 項目名 描述 作者等配置可以全部默認
先創(chuàng)建文件夾 cd到目錄下 create-react-app my-app
(注意此處名字不能有大寫)
然后 cd my-app
用npm start
啟動
組件的state應該用來存儲組件的事件處理函數(shù)隨時可能會改變的數(shù)據(jù)稽坤,以達到重新渲染并保持組件的用戶界面最新的目的
react事件觸發(fā),如onClick,onChange={this.fn.bind(this)}要用bind綁定事件以辨認
文末有貼士医增,也算是一種規(guī)范慎皱,習慣。
直接使用 BootCDN 的 React CDN 庫叶骨,地址如下:
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
react.min.js - React 的核心庫
react-dom.min.js - 提供與 DOM 相關的功能
babel.min.js - Babel 可以將 ES6 代碼轉為 ES5 代碼,這樣我們就能在目前不支持 ES6 瀏覽器上執(zhí)行 React 代碼祈匙。Babel 內嵌了對 JSX 的支持忽刽。通過將 Babel 和 babel-sublime 包(package)一同使用可以讓源碼的語法渲染上升到一個全新的水平。
ReactDOM.render( /代碼將一個 h1 標題夺欲,插入 id="example" 節(jié)點中跪帝。
<h1>Hello, world!</h1>,
document.getElementById('example')
);
JSX語法
React 使用 JSX 來替代常規(guī)的 JavaScript。
- JSX 是一個看起來很像 XML 的 JavaScript 語法擴展些阅。
- JSX 執(zhí)行更快伞剑,因為它在編譯為 JavaScript 代碼后進行了優(yōu)化。
- 它是類型安全的市埋,在編譯過程中就能發(fā)現(xiàn)錯誤黎泣。
在 JSX 中使用 JavaScript 表達式恕刘。表達式寫在花括號 {} 中
在 JSX 中不能使用 if else 語句,但可以使用 conditional (三元運算) 表達式來替代抒倚。
ReactDOM.render(
<div>
<h1>{i == 1 ? 'True!' : 'False'}</h1>
</div>
,
document.getElementById('example')
);
JSX 允許在模板中插入數(shù)組褐着,數(shù)組會自動展開所有成員:
var arr = [
<h1>菜鳥教程</h1>,
<h2>學的不僅是技術,更是夢想托呕!</h2>,
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('example')
);
1含蓉、在標簽內部的注釋需要花括號
2、在標簽外的的注釋不能使用花括號
ReactDOM.render(
/*注釋 */
<h1>孫朝陽 {/*注釋*/}</h1>,
document.getElementById('example')
);
代碼中嵌套多個 HTML 標簽项郊,需要使用一個標簽元素包裹它
React 組件
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello World馅扣!</h1>;
}
});
ReactDOM.render(
<HelloMessage />,
document.getElementById('example')
);
React.createClass 方法用于生成一個組件類 HelloMessage。
<HelloMessage /> 實例組件類并輸出信息着降。
定義的 React 類名以大寫字母開頭岂嗓,注意組件類只能包含一個頂層標簽。
如果我們需要向組件傳遞參數(shù)鹊碍,可以使用 this.props 對象:
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage name="Runoob" />,
document.getElementById('example')
);
class 屬性需要寫成 className 厌殉,for 屬性需要寫成 htmlFor ,這是因為 class 和 for 是 JavaScript 的保留字侈咕。
可以通過創(chuàng)建多個組件來合成一個組件公罕,即把組件的不同功能點進行分離。
組件名不一定是用單標簽耀销,也可以是雙標簽
<HelloMessage /> == <HelloMessage></HelloMessage>
React State(狀態(tài))
React 把組件看成是一個狀態(tài)機(State Machines)楼眷。通過與用戶的交互,實現(xiàn)不同狀態(tài)熊尉,然后渲染 UI罐柳,讓用戶界面和數(shù)據(jù)保持一致。
var LikeButton = React.createClass({
getInitialState: function() {
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? '喜歡' : '不喜歡';
return (
<p onClick={this.handleClick}>
你<b>{text}</b>我狰住。點我切換狀態(tài)张吉。
</p>
);
}
});
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
與原生 HTML 不同,on 之后第一個字母是大寫的催植。 onClick={this.handleClick}
React Props
state 和 props 主要的區(qū)別在于 props 是不可變的肮蛹,而 state 可以根據(jù)與用戶交互來改變。state 來更新和修改數(shù)據(jù)创南。 而子組件只能通過 props 來傳遞數(shù)據(jù)伦忠。
可以通過 getDefaultProps() 方法為 props 設置默認值:
var HelloMessage = React.createClass({
getDefaultProps: function() {
return {
name: 'Runoob'
};
},
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage />,
document.getElementById('example')
);
可以在父組件中設置 state, 并通過在子組件上使用 props 將其傳遞到子組件上稿辙。
React 組件 API
setState(object nextState[, function callback])
合并nextState和當前state昆码,并重新渲染組件。setState是React事件處理函數(shù)中和請求回調函數(shù)中觸發(fā)UI更新的主要方法。setState()并不會立即改變this.state赋咽,而是創(chuàng)建一個即將處理的state旧噪。setState()并不一定是同步的,為了提升性能React會批量執(zhí)行state和DOM渲染冬耿。setState()總是會觸發(fā)一次組件重繪舌菜。
- 設置狀態(tài):setState
- 替換狀態(tài):replaceState
- 設置屬性:setProps
- 替換屬性:replaceProps
- 強制更新:forceUpdate
- 獲取DOM節(jié)點:findDOMNode
- 判斷組件掛載狀態(tài):isMounted
var HelloMessage = React.createClass({
getInitialState: function() {
return {value: 'Hello Runoob!'};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function() {
var value = this.state.value;
return <div>
<input type="text" value={value} onChange={this.handleChange} />
<h4>{value}</h4>
</div>;
}
});
ReactDOM.render(
<HelloMessage />,
document.getElementById('example')
);
React小書
組件化可以幫助我們解決前端結構的復用性問題,整個頁面可以由這樣的不同的組件組合亦镶、嵌套構成日月。組件的顯示形態(tài)和行為可以由數(shù)據(jù)狀態(tài)(state)和配置參數(shù)(props)共同決定。
編譯階段你需要借助 Babel缤骨;需要 Redux 等第三方的狀態(tài)管理工具來組織代碼爱咬;如果你要寫單頁面應用那么你需要 React-router。這就是所謂的“React.js全家桶”绊起。
一個 DOM 元素包含的信息其實只有三個:標簽名精拟,屬性,子元素虱歪。
JSX 在編譯的時候會變成相應的 JavaScript 對象描述蜂绎。
我們在編寫 React.js 組件的時候,一般都需要繼承 React.js 的 Component(還有別的編寫組件的方式我們后續(xù)會提到)笋鄙。一個組件類必須要實現(xiàn)一個 render 方法师枣,這個 render 方法必須要返回一個 JSX 元素。但這里要注意的是萧落,必須要用一個外層的 JSX 元素把所有內容包裹起來践美。返回并列多個 JSX 元素是不合法的,下面是錯誤的做法:
render () {
return (
<div>第一個</div>
<div>第二個</div>
)
}
正確寫法:
render () {
return (
<div>
<div>第一個</div>
<div>第二個</div>
</div>
)
}
{} 內可以放任何 JavaScript 的代碼找岖,包括變量陨倡、表達式計算、函數(shù)執(zhí)行等等许布。 render 會把這些代碼返回的內容如實地渲染到頁面上兴革,非常的靈活。
表達式插入不僅僅可以用在標簽內部爹脾,也可以用在標簽的屬性上帖旨。
JSX 元素其實可以像 JavaScript 對象那樣自由地賦值給變量,或者作為函數(shù)參數(shù)傳遞灵妨、或者作為函數(shù)的返回值。
作為變量:
const isGoodWord = true
const goodWord = <strong> is good</strong>
const badWord = <span> is not good</span>
{isGoodWord ? goodWord : badWord}
// 作為函數(shù):
renderGoodWord (goodWord, badWord) {
const isGoodWord = true
return isGoodWord ? goodWord : badWord
} // 偽代碼
{this.renderGoodWord(
<strong> is good</strong>,
<span> is not good</span>
)}
自定義的組件都必須要用大寫字母開頭落竹,普通的 HTML 標簽都用小寫字母開頭泌霍。
class Index extends Component {
render () {
return (
<div>
<Header />
<Main />
<Footer />
</div>
)}}
ReactDOM.render(
<Index />,
document.getElementById('root')
) //組件間的嵌套 樹狀結構
React.js 監(jiān)聽事件
只需要給需要監(jiān)聽事件的元素加上屬性類似于 onClick、onKeyDown 這樣的屬性。
React.js 幫我們封裝好了一系列的 on* 的屬性朱转,當你需要為某個元素監(jiān)聽某個事件的時候蟹地,只需要簡單地給它加上 on* 就可以了。這些事件屬性名都必須要用駝峰命名法藤为。
這些 on* 的事件監(jiān)聽只能用在普通的 HTML 的標簽上怪与,而不能用在組件標簽上。也就是說缅疟,<Header onClick={…} /> 這樣的寫法不會有什么效果的分别。
事件監(jiān)聽函數(shù)會被自動傳入一個 event 對象,event 對象并不是瀏覽器提供的存淫,而是它自己內部所構建的耘斩。
class Title extends Component {
handleClickOnTitle (e) {
console.log(e.target.innerHTML) }
render () {
return (
<h1 onClick={this.handleClickOnTitle.bind(this)}>React 小書</h1>
) }
}
關于事件中的 this
React.js 調用你所傳給它的方法的時候,并不是通過對象方法的方式調用(this.handleClickOnTitle)桅咆,而是直接通過函數(shù)調用 (handleClickOnTitle)括授,所以事件監(jiān)聽函數(shù)內并不能通過 this 獲取到實例。如果你想在事件函數(shù)當中使用當前的實例岩饼,你需要手動地將實例方法 bind 到當前實例上再傳入給 React.js荚虚。bind 會把實例方法綁定到當前實例上,然后我們再把綁定后的函數(shù)傳給 React.js 的 onClick 事件監(jiān)聽籍茧。
bind 不僅可以幫我們把事件監(jiān)聽方法中的 this 綁定到當前組件實例上版述;還可以幫助我們在在渲染列表元素的時候,把列表元素傳入事件監(jiān)聽函數(shù)當中硕糊,后面會介紹院水。
class LikeButton extends Component {
constructor () {
super()
this.state = { isLiked: false } // 這個對象在構造函數(shù)里面初始化
}
handleClickOnLikeButton () {
this.setState({ // setState 函數(shù),每次點擊都會更新 isLiked 屬性
isLiked: !this.state.isLiked })
}
}
setState 方法由父類 Component 所提供简十。
React.js 內部會把 JavaScript 事件循環(huán)中的消息隊列的同一個消息中的 setState 都進行合并以后再重新渲染組件檬某。所以并不需要擔心多次進行 setState 會帶來性能問題。
組件內部是通過 this.props 的方式獲取到組件的參數(shù)的螟蝙,如果 this.props 里面有需要的屬性我們就采用相應的屬性恢恼,沒有的話就用默認的屬性。
在使用一個組件的時候胰默,可以把參數(shù)放在標簽的屬性當中场斑,所有的屬性都會作為 props 對象的鍵值:
class Index extends Component {
render () {
return (
<div>
<LikeButton likedText='已贊' unlikedText='贊' />
</div>
) }
}
前面的章節(jié)我們說過,JSX 的表達式插入可以在標簽屬性上使用牵署。所以其實可以把任何類型的數(shù)據(jù)作為組件的參數(shù)漏隐,包括字符串、數(shù)字奴迅、對象青责、數(shù)組、甚至是函數(shù)等等:
<LikeButton wordings={{likedText: '已贊', unlikedText: '贊'}} />
JSX 的 {} 內可以嵌入任何表達式,{{}} 就是在 {} 內部用對象字面量返回一個對象而已脖隶。
static defaultProps = { //如果沒有傳進來扁耐,會直接使用 defaultProps 中的默認屬性。
likedText: '取消',
unlikedText: '點贊'
} //defaultProps 作為點贊按鈕組件的類屬性产阱,里面是對 props 中各個屬性的默認配置婉称。
state 是讓組件控制自己的狀態(tài),props 是讓外部對組件自己進行配置构蹬。盡量少地用 state王暗,盡量多地用 props怎燥。因為狀態(tài)會帶來管理的復雜性,我們盡量多地寫無狀態(tài)組件策肝,盡量少地寫有狀態(tài)的組件。這樣會降低代碼維護的難度隐绵,也會在一定程度上增強組件的可復用性之众。
渲染列表數(shù)據(jù)
一般來說棺禾,在 React.js 處理列表就是用 map 來處理、渲染的峭跳。
{ users.map((user) => <User user = {user} />) }
對于用表達式套數(shù)組羅列到頁面上的元素膘婶,都要為每個元素加上 key 屬性蛀醉,這個 key 必須是每個元素唯一的標識。一般來說拯刁,key 的值可以直接后臺數(shù)據(jù)返回的 id垛玻,因為后臺的 id 都是唯一的。
{ users.map((user, i) => <User key={i} user={user} />)}
在實際項目當中帚桩,如果你的數(shù)據(jù)順序可能發(fā)生變化账嚎,標準做法是最好是后臺數(shù)據(jù)返回的 id 作為列表元素的 key参淹。
React.js生命周期
React.js 將組件渲染,并且構造 DOM 元素然后塞入頁面的過程稱為組件的掛載(這個定義請好好記卓也弧)烟勋。
掛載階段
React.js 會在組件的 render 之前調用 componentWillMount,在 DOM 元素塞入頁面以后調用 componentDidMount阻肿。而componentWillUnmount控制了這個組件的刪除過程沮尿。
-> constructor()
-> componentWillMount()
-> render()
// 然后構造 DOM 元素插入頁面
-> componentDidMount()
// ...
// 即將從頁面中刪除
-> componentWillUnmount()
// 從頁面中刪除
我們一般會把組件的 state 的初始化工作放在 constructor 里面去做畜疾;
在 componentWillMount 進行組件的啟動工作,例如 Ajax 數(shù)據(jù)拉取姥敛、定時器的啟動瞎暑;組件從頁面上銷毀的時候,有時候需要一些數(shù)據(jù)的清理墨榄,例如定時器的清理揍拆,就會放在 componentWillUnmount 里面去做嫂拴。如下:
constructor () {
super()
this.state = {
date: new Date()
}
}
每隔 1 秒更新中的 state.date,這樣頁面就可以動起來了猪狈。
componentWillMount () {
this.timer = setInterval(() => {
this.setState({ date: new Date() })
}, 1000)
}
現(xiàn)頁面上有個按鈕可顯示或者隱藏時鐘辩恼,當時鐘隱藏的時候谓形,我們并沒有清除定時器寒跳。
添加 componentWillUnmount竹椒,在組件銷毀的時候清除該組件的定時器:
componentWillUnmount () {
clearInterval(this.timer)
}
更新階段(說白了就是 setState胸完,先了解即可)
shouldComponentUpdate(nextProps, nextState):你可以通過這個方法控制組件是否重新渲染。如果返回 false 組件就不會重新渲染爆惧。這個生命周期在 React.js 性能優(yōu)化上非常有用锨能。
componentWillReceiveProps(nextProps):組件從父組件接收到新的 props 之前調用。
componentWillUpdate():組件開始重新渲染之前調用叔收。
componentDidUpdate():組件重新渲染并且把更改變更到真實的 DOM 以后調用饺律。
ref屬性
React.js 當中提供了 ref 屬性來幫助我們獲取已經(jīng)掛載的元素的 DOM 節(jié)點跺株,你可以給某個 JSX 元素加上 ref屬性:
componentDidMount () {
this.input.focus()
}
render () {
return (
<input ref={(input) => this.input = input} />
) }
} //我們就可以通過 this.input 獲取到這個 DOM 元素乒省。
就可以在 componentDidMount 中使用這個 DOM 元素。并且調用 this.input.focus() 的 DOM API砸泛。
但是記住一個原則:能不用 ref 就不用蛆封。不利于我們理解和維護惨篱。
其實可以給組件標簽也加上 ref ,例如:
<Clock ref={(clock) => this.clock = clock} />
props.children
組件本身是一個不帶任何內容的方形的容器琢融,可以在用這組件的時候給它傳入任意內容
嵌套的結構在組件內部都可以通過 props.children 獲取到,這種組件編寫方式在編寫容器類型的組件當中非常有用宿亡。而在實際的 React.js 項目當中奋蔚,我們幾乎每天都需要用這種方式來編寫組件泊碑。
http://huziketang.com/books/react/lesson22
{this.props.children}
React.js 就是把我們嵌套的 JSX 元素一個個都放到數(shù)組當中毯欣,然后通過 props.children 傳給了Card
dangerouslySetHTML 和 style 屬性
render () {
return (
<div
className='editor-wrapper'
dangerouslySetInnerHTML={{__html: this.state.content}} />
) }
需要給 dangerouslySetInnerHTML 傳入一個對象酗钞,這個對象的 __html 屬性值就相當于元素的 innerHTML,這樣我們就可以動態(tài)渲染元素的 innerHTML 結構了窘奏。因為設置 innerHTML 可能會導致跨站腳本攻擊(XSS).這個屬性不必要的情況就不要使用葫录。
style 接受一個對象米同,這個對象里面是這個元素的 CSS 屬性鍵值對,原來 CSS 屬性中帶 - 的元素都必須要去掉 - 換成駝峰命名少孝,如 font-size 換成 fontSize熬苍,text-align 換成 textAlign柴底。我們用 setState 就可以修改樣式。
<h1 style={{fontSize: '12px', color: this.state.color}}>React.js 小書</h1>
只要簡單地 setState({color: 'blue'}) 就可以修改元素的顏色成藍色盖淡。
React 提供的第三方庫 prop-types
通過 PropTypes 給組件的參數(shù)做類型限制凿歼,這在構建大型應用程序的時候特別有用。
npm install --save prop-types
http://huziketang.com/books/react/lesson24
在文件頭部引入了 PropTypes import PropTypes from 'prop-types'
并且給 Comment 組件類添加了類屬性 propTypes掀抹,里面的內容的意思就是你傳入的 comment 類型必須為 object(對象)心俗。isRequired 關鍵字來強制組件某個參數(shù)必須傳入.:
static propTypes = {
comment: PropTypes.object.isRequired
}
貼士
組件的私有方法都用 _ 開頭城榛,所有事件監(jiān)聽的方法都用 handle 開頭。把事件監(jiān)聽方法傳給組件的時候疟位,屬性名用 on 開頭喘垂。監(jiān)聽(on)CommentInput 的 Submit 事件,并且交給 this 去處理(handle)得院。這樣思路非常清晰祥绞。
<CommentInput onSubmit={this.handleSubmitComment.bind(this)} />
組件的內容編寫順序如下:
- static 開頭的類屬性阱驾,如 defaultProps里覆、propTypes。
- 構造函數(shù)虹统,constructor隧甚。
- getter/setter(還不了解的同學可以暫時忽略)戚扳。
- 組件生命周期。
- _ 開頭的私有方法珠增。
- 事件監(jiān)聽方法,handle*巍举。
- render開頭的方法懊悯,有時候 render() 方法里面的內容會分開到不同函數(shù)里面進行梦皮,這些函數(shù)都以 render 開頭。
- render() 方法欠窒。
React Router
npm install -S react-router
使用時,路由器Router就是React的一個組件型将。
import { Router } from 'react-router';
render(<Router/>, document.getElementById('app'));
Router組件本身只是一個容器七兜,真正的路由要通過Route組件定義。
import { Router, Route, hashHistory } from 'react-router';
render((
<Router history={hashHistory}>
<Route path="/" component={App}/>
</Router>
), document.getElementById('app'));
用戶訪問根路由/(比如http://www.example.com/)惜犀,組件APP就會加載到document.getElementById('app')虽界。Router組件有一個參數(shù)history涛菠,它的值hashHistory表示俗冻,路由的切換由URL的hash變化決定,即URL的#部分發(fā)生變化琅关。舉例來說讥蔽,用戶訪問http://www.example.com/,實際會看到的是http://www.example.com/#/色罚。
Route組件定義了URL路徑與組件的對應關系账劲。你可以同時使用多個Route組件瀑焦。
<Router history={hashHistory}>
<Route path="/" component={App}/>
<Route path="/repos" component={Repos}/>
<Route path="/about" component={About}/>
</Router>
上面代碼中,用戶訪問/repos(比如http://localhost:8080/#/repos)時铺董,加載Repos組件精续;訪問/about(http://localhost:8080/#/about)時粹懒,加載About組件凫乖。
嵌套路由
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="/repos" component={Repos}/>
<Route path="/about" component={About}/>
</Route>
</Router>
上面代碼,用戶訪問/repos時删掀,會先加載App組件披泪,然后在它的內部再加載Repos組件菊匿。
<App>
<Repos/>
</App>
this.props.children屬性就是子組件跌捆。
path 屬性
Route組件的path屬性指定路由的匹配規(guī)則。這個屬性是可以省略的姆钉,這樣的話,不管路徑是否匹配陶冷,總是會加載指定組件埂伦。
<Route path="inbox" component={Inbox}>
<Route path="messages/:id" component={Message} />
</Route>
當用戶訪問 /inbox/messages/:id 時思恐,會加載下面的組件胀莹。
<Inbox>
<Message/>
</Inbox>
如果省略外層Route的path參數(shù),寫成下面的樣子媳否。
<Route component={Inbox}>
<Route path="inbox/messages/:id" component={Message} />
</Route>
現(xiàn)在用戶訪問 /inbox/messages/:id 時篱竭,組件加載還是原來的樣子步绸。
path屬性可以使用通配符靡努。
<Route path="/hello/:name">
// 匹配 /hello/michael
// 匹配 /hello/ryan
<Route path="/hello(/:name)">
// 匹配 /hello
// 匹配 /hello/michael
// 匹配 /hello/ryan
<Route path="/files/*.*">
// 匹配 /files/hello.jpg
// 匹配 /files/hello.html
<Route path="/files/*">
// 匹配 /files/
// 匹配 /files/a
// 匹配 /files/a/b
<Route path="/**/*.jpg">
// 匹配 /files/hello.jpg
// 匹配 /files/path/to/file.jpg
通配符的規(guī)則如下惑朦。
(1):paramName
:paramName匹配URL的一個部分漓概,直到遇到下一個/胃珍、?、#為止吩蔑。這個路徑參數(shù)可以通過this.props.params.paramName取出填抬。
(2)()
()表示URL的這個部分是可選的。
(3)*
*匹配任意字符仆潮,直到模式里面的下一個字符為止遣臼。匹配方式是非貪婪模式揍堰。
(4) **
** 匹配任意字符,直到下一個/篡石、?凰萨、#為止械馆。匹配方式是貪婪模式霹崎。
路由匹配規(guī)則是從上到下執(zhí)行,一旦發(fā)現(xiàn)匹配境析,就不再其余的規(guī)則了劳淆。
設置路徑參數(shù)時默赂,需要特別小心這一點缆八。
<Router>
<Route path="/:userName/:id" component={UserPage}/>
<Route path="/about/me" component={About}/>
</Router>
IndexRoute 組件
顯式指定Home是根路由的子組件奈辰,即指定默認情況下加載的子組件。你可以把IndexRoute想象成某個路徑的index.html底哥。
<Router>
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path="accounts" component={Accounts}/>
<Route path="statements" component={Statements}/>
</Route>
</Router>
用戶訪問 / 的時候趾徽,加載的組件結構如下。
<App>
<Home/>
</App>
App只包含下級組件的共有元素疲酌,本身的展示內容則由Home組件定義朗恳。這樣有利于代碼分離载绿,也有利于使用React Router提供的各種API崭庸。
Redirect 組件
<Redirect>組件用于路由的跳轉怕享,即用戶訪問一個路由,會自動跳轉到另一個路由沙合。
<Route path="inbox" component={Inbox}>
{/* 從 /inbox/messages/:id 跳轉到 /messages/:id */}
<Redirect from="messages/:id" to="/messages/:id" />
</Route>
現(xiàn)在訪問 /inbox/messages/5首懈,會自動跳轉到/messages/5猜拾。
IndexRedirect組件用于訪問根路由的時候佣盒,將用戶重定向到某個子組件肥惭。
<Route path="/" component={App}>
<IndexRedirect to="/welcome" />
<Route path="welcome" component={Welcome} />
<Route path="about" component={About} />
</Route>
用戶訪問根路徑時蜜葱,將自動重定向到子組件welcome耀石。
Link
Link組件用于取代<a>元素,生成一個鏈接炕贵,允許用戶點擊后跳轉到另一個路由野崇。它基本上就是<a>元素的React 版本乓梨,可以接收Router的狀態(tài)扶镀。
render() {
return <div>
<ul role="nav">
<li><Link to="/about">About</Link></li>
<li><Link to="/repos">Repos</Link></li>
</ul>
</div>
}
如果鏈接到根路由/臭觉,不要使用Link組件,而要使用IndexLink組件忆肾。
histroy 屬性
Router組件的history屬性客冈,用來監(jiān)聽瀏覽器地址欄的變化稳强,并將URL解析成一個地址對象退疫,供 React Router 匹配褒繁。
history屬性,一共可以設置三種值燕差。
- browserHistory
- hashHistory
- createMemoryHistory
如果設為hashHistory徒探,路由將通過URL的hash部分(#)切換喂窟,URL的形式類似example.com/#/some/path
如果設為browserHistory,瀏覽器的路由就不再通過Hash完成了质和,而顯示正常的路徑example.com/some/path
但是侦另,這種情況需要對[服務器改造])褒傅。