React.js

函數(shù)是面向過程的漠魏,函數(shù)的調用不需要主體澳厢,而方法是屬于對象的鸦采,調用方法需要一個主體-即對象篙骡。

npm install -g create-react-app
創(chuàng)建react項目(具體看react-commend) 項目名 描述 作者等配置可以全部默認
先創(chuàng)建文件夾 cd到目錄下 create-react-app my-app(注意此處名字不能有大寫)
然后 cd my-appnpm 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)} />

組件的內容編寫順序如下:

  1. static 開頭的類屬性阱驾,如 defaultProps里覆、propTypes。
  2. 構造函數(shù)虹统,constructor隧甚。
  3. getter/setter(還不了解的同學可以暫時忽略)戚扳。
  4. 組件生命周期。
  5. _ 開頭的私有方法珠增。
  6. 事件監(jiān)聽方法,handle*巍举。
  7. render開頭的方法懊悯,有時候 render() 方法里面的內容會分開到不同函數(shù)里面進行梦皮,這些函數(shù)都以 render 開頭。
  8. render() 方法欠窒。

React ES5 與 ES6 區(qū)別

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 但是侦另,這種情況需要對[服務器改造])褒傅。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末殿托,一起剝皮案震驚了整個濱河市剧蚣,隨后出現(xiàn)的幾起案子鸠按,更是在濱河造成了極大的恐慌目尖,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扯罐,居然都是意外死亡烦衣,警方通過查閱死者的電腦和手機花吟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門示辈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人遣蚀,你說我怎么就攤上這事矾麻∩闯埽” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵险耀,是天一觀的道長弄喘。 經(jīng)常有香客問我,道長甩牺,這世上最難降的妖魔是什么蘑志? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任贬派,我火速辦了婚禮急但,結果婚禮上,老公的妹妹穿的比我還像新娘搞乏。我一直安慰自己波桩,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布请敦。 她就那樣靜靜地躺著镐躲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪侍筛。 梳的紋絲不亂的頭發(fā)上萤皂,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音匣椰,去河邊找鬼裆熙。 笑死,一個胖子當著我的面吹牛窝爪,可吹牛的內容都是我干的弛车。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蒲每,長吁一口氣:“原來是場噩夢啊……” “哼纷跛!你這毒婦竟也來了?” 一聲冷哼從身側響起邀杏,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤贫奠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后望蜡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體唤崭,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年脖律,在試婚紗的時候發(fā)現(xiàn)自己被綠了谢肾。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡小泉,死狀恐怖芦疏,靈堂內的尸體忽然破棺而出冕杠,到底是詐尸還是另有隱情,我是刑警寧澤酸茴,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布分预,位于F島的核電站,受9級特大地震影響薪捍,放射性物質發(fā)生泄漏笼痹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一酪穿、第九天 我趴在偏房一處隱蔽的房頂上張望凳干。 院中可真熱鬧,春花似錦昆稿、人聲如沸纺座。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽净响。三九已至,卻和暖如春喳瓣,著一層夾襖步出監(jiān)牢的瞬間馋贤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工畏陕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留配乓,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓惠毁,卻偏偏與公主長得像犹芹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鞠绰,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容