阮一峯老師的github地址:React Demos javascript
React 入門實例教程html
<!DOCTYPE html> <html> <head> // react 核心庫 <script src="../build/react.js"></script> // react 操做 DOM 庫 <script src="../build/react-dom.js"></script> // 將 JSX 語法轉化爲 js 語法 <script src="../build/browser.min.js"></script> </head> <body> <div id="example"></div> // 使用 balel 解析jsx 語法 <script type="text/babel"> // ** Our code goes here! ** </script> </body> </html>
// ReactDOM.render() 將模板轉化爲 HTML 語言 ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('example') );
var names = ['Alice', 'Emily', 'Kate']; ReactDOM.render( <div> { names.map(function (name) { return <div>Hello, {name}!</div> }) } </div>, document.getElementById('example') );
在參數一中,{}
中能夠鍵入javascript
代碼,能夠用來遍歷數組,對象等;在其中可使用return
來返回標籤。vue
JSX 的基本語法規則:遇到 HTML 標籤(以 <
開頭),就用 HTML 規則解析;遇到代碼塊(以 {
開頭),就用 JavaScript 規則解析。java
數組直接寫在{}
中就能遍歷,以下:數組直接就遍歷了,展開這個數組的全部成員。react
var arr = [ <h1 key="1">Hello world!</h1>, <h2 key="2">React is awesome</h2>, ]; ReactDOM.render( <div>{arr}</div>, document.getElementById('example') );
<div id="example"></div> <script type="text/babel"> class HelloMessage extends React.Component { render() { return <h1>Hello {this.props.name}</h1>; } } // 使用 this.props 接收組件標籤的屬性 是一個對象 ReactDOM.render( <HelloMessage name="John" />, document.getElementById('example') ); </script>
git
組件類只能包含一個頂層標籤github
組件類必須有 / 結尾api
全部組件類都必須有本身的 render 方法,用於輸出組件數組
babel
把NotesList
下的全部子節點渲染到 ol li
中
<div id="example"></div> <script type="text/babel"> class NotesList extends React.Component { render() { return ( <ol> { React.Children.map(this.props.children, function (child) { return <li>{child}</li>; }) } </ol> ); } } // this.props.children 表示組件上的子節點 ReactDOM.render( <NotesList> <span>45645</span> <span>hello</span> <span>world</span> </NotesList>, document.getElementById('example') ); </script>
指定組件中的屬性類型
<div id="example"></div> <script type="text/babel"> var data = 123; class MyTitle extends React.Component { static propTypes = { title: PropTypes.string.isRequired, } render() { return <h1> {this.props.title} </h1>; } } ReactDOM.render( <MyTitle title={data} />, document.getElementById('example') ); </script>
二、組件 MyComponent
的子節點有一個文本輸入框,用於用戶輸入,這時就必須獲取真實的DOM節點,虛擬DOM是拿不到用戶輸入的數據的
爲了作到這一點,文本輸入框必須有一個ref
屬性,而後this.ref.[refName]
就會返回這個真實的DOM節點。
須要注意的是,因爲 this.refs.[refName]
屬性獲取的是真實 DOM ,因此必須等到虛擬 DOM 插入文檔之後,才能使用這個屬性,不然會報錯。
代碼中,經過爲組件指定 Click
事件的回調函數,確保了只有等到真實 DOM 發生 Click
事件以後,纔會讀取 this.refs.[refName]
屬性。
<div id="example"></div> <script type="text/babel"> class MyComponent extends React.Component { constructor(props) { super(props); this.myTextInput = React.createRef(); this.handleClick = this.handleClick.bind(this) } handleClick() { console.log('object'); this.myTextInput.current.focus(); } render() { return ( <div> <input type="text" ref={this.myTextInput} /> <input type="button" value="Focus the text input" onClick={this.handleClick} /> </div> ); } } ReactDOM.render( <MyComponent />, document.getElementById('example') ); </script>
<div id="example"></div> <script type="text/babel"> class LikeButton extends React.Component { // 構造器建立 state constructor(props) { super(props) this.state = { liked: false } // p標籤上的 方法 this.handleClick = this.handleClick.bind(this) } handleClick(event) { // state 下的 liked 狀態改變 this.setState({ liked: !this.state.liked }); } render() { var text = this.state.liked ? 'like' : 'haven\'t liked'; return ( <p onClick={this.handleClick}> You {text} this. Click to toggle. </p> ); } } ReactDOM.render( <LikeButton />, document.getElementById('example') ); </script>
上面代碼是一個
LikeButton
組件,構造器函數定義 state 狀態,這是一個對象,能夠經過this.state屬性讀取,當用戶點擊組件時,狀態改變,this.setState() 方法就修改狀態值,每次修改之後,自動調用this.render方法,再次渲染組件。
因爲 this.props
和 this.state
都用於描述組件的特性,可能會產生混淆。
一個簡單的區分方法是,this.props
表示那些一旦定義,就再也不改變的特性,而 this.state
是會隨着用戶互動而產生變化的特性。
<div id="example"></div> <script type="text/babel"> class Input extends React.Component { constructor(props) { super(props) this.state = { value: 'Hello!' } this.handleChange = this.handleChange.bind(this) } handleChange(event) { // 設置 input 的值 this.setState({ value: event.target.value }); } render() { var value = this.state.value; return ( <div> <input type="text" value={value} onChange={this.handleChange} /> <p>{value}</p> </div> ); } } ReactDOM.render(<Input/>, document.getElementById('example')); </script>
組件的生命週期分爲三個狀態:
Mounting: 一插入真實的DOM
Updating: 正在被從新渲染
Unmounting: 以移除真實 DOM
componentWillMount() 組件掛載以前調用,render()以前調用
componentDidMount() DOM渲染完成後調用,能夠用於加載後臺數據
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState) 組件更新時觸發該方法,初始渲染不調用
componentWillUnmount() 組件被銷燬以前通常用於清理工做(定時器timer、網絡請求、訂閱事件)
此外,React 還提供兩種特殊狀態的處理函數。
componentWillReceiveProps(object nextProps):已加載組件收到新的參數時調用
shouldComponentUpdate(object nextProps, object nextState):組件判斷是否從新渲染時調用
<div id="example"></div> <script type="text/babel"> class Hello extends React.Component { constructor(props) { super(props) this.state = { opacity: 1.0 }; } // 已插入真實 DOM 函數在進入狀態以後調用 componentDidMount() { this.timer = setInterval(function () { // 將狀態機的變量賦值給 opacity var opacity = this.state.opacity; // 定時 -0.05 opacity -= .05; if (opacity < 0.1) { opacity = 1.0; } // 從新賦值給 state this.setState({ opacity: opacity }); }.bind(this), 100); } render() { return ( <div style={{opacity: this.state.opacity}}> Hello {this.props.name} </div> ); } } // 添加到 DOM 中 ReactDOM.render( <Hello name="world"/>, document.getElementById('example') ); </script>
使用 jQuery 完成 Ajax 請求
<div id="example"></div> <script type="text/babel"> class UserGist extends React.Component { constructor(props) { super(props) this.state = { username: '', lastGistUrl: '' } } componentDidMount() { $.get(this.props.source, function(result) { var lastGist = result[0]; this.setState({ username: lastGist.owner.login, lastGistUrl: lastGist.html_url }); }.bind(this)); } render() { return ( <div> {this.state.username}'s last gist is <a href={this.state.lastGistUrl}>here</a>. </div> ); } } ReactDOM.render( <UserGist source="https://api.github.com/users/octocat/gists" />, document.getElementById('example') ); </script>