在使用React 0.14版本時,需要引入react.js/react-dom.js/browser.min.js
### ReactDOM.render
ReactDOM.render()將JSX轉換成HTML,并且將其插入特定的DOM節點。在0.14版本之前,使用的是React.render()方法,目前還支持,但是React不推薦使用。
~~~
<body>
<div id = "container"></div>
</body>
</html>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script type="text/babel">
ReactDOM.render(
<h1>Hello, world!</h1>,
document.querySelector('#container')
);
</script>
~~~
上面代碼一共用了三個庫: react.js 、react-dom.js 和 browser.js ,它們必須首先加載。最后一個?`<script>`?標簽的 type 屬性為 text/babel 。這是因為 React 獨有的 JSX 語法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type=”text/babel” 。?
react.js 是 React 的核心庫,react-dom.js 是提供與 DOM 相關的功能,browser.js 的作用是將 JSX 語法轉為 JavaScript 語法,這一步很消耗時間,實際上線的時候,應該將它放到服務器完成,在V0.14版本之前,react使用 JSTransform.js 解析?`<script type="text/jsx">`?
react不依賴于jquery,我們可以使用jquery,但是render里面的第二個參數必須使用Javascript原生的方法,不能用jquery來選取DOM節點。
### JSX語法
HTML 語言直接寫在 JavaScript 語言之中,不加任何引號,這就是 JSX 的語法,它允許 HTML 與 JavaScript 的混寫。?
JSX 的基本語法規則:遇到 HTML 標簽(以<開頭),就用 HTML 規則解析;遇到代碼塊(以{開頭),就用 JavaScript 規則解析。
~~~
<body>
<div id = "example"></div>
</body>
</html>
<script src = "build/react.js"></script>
<script src = "build/react-dom.js"></script>
<script src = "build/browser.min.js"></script>
<script type = "text/babel">
var names = ["Alice", "Emily", "Kate"];
ReactDOM.render(
<div>
{
names.map(function(name){
return <div>Hello, {name}</div>
})
}
</div>,
document.querySelector("#example")
)
</script>
~~~
?
從生成的Html代碼,我們可以看出,每一個Html標簽都有一個data-reactid屬性。?
JSX允許直接在模板插入 JavaScript 變量。如果這個變量是一個數組,則會展開這個數組的所有成員。
~~~
<body>
<div id = "example"></div>
</body>
</html>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="build/browser.min.js"></script>
<script type="text/babel">
var arry = [
<h1>Hello world</h1>,
<h2>React is awesome</h2>
];
ReactDOM.render(
<div>{arry}</div>,
document.querySelector("#example")
);
</script>
~~~

### 組件
React 允許將代碼封裝成組件(component),然后像插入普通 HTML 標簽一樣,在網頁中插入這個組件。React.createClass 方法就用于生成一個組件類.
~~~
<body>
<div id = "example"></div>
<div id = "container"></div>
</body>
</html>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="build/browser.min.js"></script>
<script type="text/babel">
var HelloMessage = React.createClass({
render: function(){
return <h1>Hello{this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage name = "John" />,
document.querySelector("#example")
);
ReactDOM.render(
<HelloMessage name = "Yvette" />,
document.querySelector("#container")
);
</script>
~~~
變量 HelloMessage就是一個組件類。模板插入 時,會自動生成 HelloMessage的一個實例,每個組件都有render方法,這是組件最基本的方法。此外,還必須注意的是,組件類的首字母必須大寫,否則React會將其視為普通的html標簽,但是,html中又無此標簽,就會報錯。?
?
組件類只能包含一個頂層標簽,否則也會報錯。
~~~
<body>
<div id = "example"></div>
</body>
</html>
<script src = "build/react.js"></script>
<script src = "build/react-dom.js"></script>
<script src = "build/browser.min.js"></script>
<script type="text/babel">
var HelloMessage = React.createClass({
render: function(){
return <h1>Hello {this.props.name}
</h1><p>Are you happy?</p>
}
});
ReactDOM.render(
<HelloMessage name = "Yvette"/>,
document.querySelector("#example")
);
</script>
~~~
上面代碼會報錯,因為HelloMessage組件包含了兩個頂層標簽:h1和p?
組件的用法與原生的 HTML 標簽完全一致,可以任意加入屬性,比如 ,就是 HelloMessage 組件加入一個 name 屬性,值為 John。組件的屬性可以在組件類的 this.props 對象上獲取,比如 name 屬性就可以通過 this.props.name 讀取。?
添加組件屬性,有一個地方需要注意,就是 class 屬性需要寫成 className ,for 屬性需要寫成 htmlFor ,這是因為 class 和 for 是 JavaScript 的保留字。
### this.props.children
this.props 對象的屬性與組件的屬性一一對應,但是有一個例外,就是 this.props.children 屬性。它表示組件的所有子節點
~~~
<script type="text/babel">
var NodeList = React.createClass({
render: function(){
return(
<ol>
{
React.Children.map(this.props.children, function (child) {
return <li>{child}</li>;
})
}
</ol>
);
}
});
ReactDOM.render(
<NodeList>
<span>Dream</span>
<span>Future</span>
</NodeList>,
document.querySelector("#example")
);
</script>
~~~
NoteList 組件有兩個 span 子節點,它們都可以通過 this.props.children 讀取,運行結果如下。?
?
需要注意, this.props.children 的值有三種可能:如果當前組件沒有子節點,它就是 undefined;如果有一個子節點,數據類型是 object;如果有多個子節點,數據類型就是 array。所以,處理 this.props.children 的時候要小心。?
React 提供一個工具方法React.Children來處理 this.props.children 。我們可以用 React.Children.map 來遍歷子節點,而不用擔心 this.props.children 的數據類型是 undefined 還是 object。
### PropTypes
組件的屬性可以接受任意值,字符串、對象、函數等等都可以。有時,我們需要一種機制,驗證別人使用組件時,提供的參數是否符合要求。?
組件類的PropTypes屬性,就是用來驗證組件實例的屬性是否符合要求,如果引入的是react.min.js,那么此屬性沒有作用,控制臺不會報錯。當前版本是V0.14.8
~~~
<script src = "build/react.js"></script>
<script src = "build/react-dom.js"></script>
<script src = "build/browser.min.js"></script>
<script type="text/babel">
var MyTitle = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired,
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
var data = 123;
ReactDOM.render(
<MyTitle title={data} />,
document.body
);
</script>
~~~
?
getDefaultProps方法可以用來設置組件屬性的默認值
~~~
<script type="text/babel">
var MyTitle = React.createClass({
getDefaultProps: function(){
return{
title: "Hello World"
};
},
render: function(){
return <h1> {this.props.title} </h1>;
}
});
ReactDOM.render(
<MyTitle />,
document.querySelector("#example")
)
</script>
~~~
### 獲取真實的DOM節點
組件并不是真實的 DOM 節點,而是存在于內存之中的一種數據結構,叫做虛擬 DOM (virtual DOM)。只有當它插入文檔以后,才會變成真實的 DOM 。根據 React 的設計,所有的 DOM 變動,都先在虛擬 DOM 上發生,然后再將實際發生變動的部分,反映在真實 DOM上,這種算法叫做 DOM diff ,它可以極大提高網頁的性能表現。?
附上DOM diff的流程圖:?
?
但是,有時需要從組件獲取真實 DOM 的節點,這時就要用到ref屬性。
~~~
<script type="text/babel">
var MyComponent = React.createClass({
handleClick: function(){
this.refs.myTextInput.focus();
},
render: function(){
return (
<div>
<input type = "text" ref = "myTextInput" />
<input type = "button" value = "Focus the text input" onClick = {this.handleClick} />
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.querySelector("#example")
)
</script>
~~~
組件 MyComponent的子節點有一個文本輸入框,用于獲取用戶的輸入。這時就必須獲取真實的 DOM 節點,虛擬 DOM 是拿不到用戶輸入的。為了做到這一點,文本輸入框必須有一個 ref屬性,然后 this.refs.[refName] 就會返回這個真實的 DOM 節點。?
需要注意的是,由于 this.refs.[refName] 屬性獲取的是真實 DOM ,所以必須等到虛擬 DOM 插入文檔以后,才能使用這個屬性,否則會報錯。上面代碼中,通過為組件指定 Click 事件的回調函數,確保了只有等到真實 DOM 發生 Click事件之后,才會讀取 this.refs.[refName] 屬性。?
React 組件支持很多事件,除了 Click 事件以外,還有 KeyDown 、Copy、Scroll 等。
### this.state
React 的一大創新,就是將組件看成是一個狀態機,一開始有一個初始狀態,然后用戶互動,導致狀態變化,從而觸發重新渲染 UI。
~~~
<script type="text/babel">
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 ? "like" : "haven\'t like";
return (
<p onClick = {this.handleClick}>
You {text} this. Click to toggle.
</p>
);
}
});
ReactDOM.render(
<LikeButton />,
document.querySelector("#example")
);
</script>
~~~
上面代碼是一個 LikeButton組件,它的 getInitialState方法用于定義初始狀態,也就是一個對象,這個對象可以通過 this.state 屬性讀取。當用戶點擊組件,導致狀態變化,this.setState 方法就修改狀態值,每次修改以后,自動調用 this.render 方法,再次渲染組件。?
由于 this.props 和 this.state 都用于描述組件的特性,可能會產生混淆。一個簡單的區分方法是,this.props 表示那些一旦定義,就不再改變的特性,而 this.state 是會隨著用戶互動而產生變化的特性。
### 表單
用戶在表單填入的內容,屬于用戶跟組件的互動,所以不能用 this.props 讀取。
~~~
<script type="text/babel">
var Input = React.createClass({
getInitialState: function(){
return {value: "Hello"};
},
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} />
<p>{value}</p>
</div>
);
}
});
ReactDOM.render(
<Input />,
document.querySelector("#example")
)
</script>
~~~
文本輸入框的值,不能用 this.props.value 讀取,而要定義一個 onChange事件的回調函數,通過 event.target.value 讀取用戶輸入的值。textarea 元素、select元素、radio元素都屬于這種情況
- 前言
- jQuery輪播圖插件
- JS模擬事件操作
- JS閉包與變量
- JS綁定事件
- HTML5之file控件
- JavaScript的this詞法
- JavaScript的this詞法(二)
- JS this詞法(三)
- JS檢測瀏覽器插件
- JS拖拽組件開發
- number輸入框
- Modernizr.js和yepnode.js
- DOM變化后事件綁定失效
- div和img之間的縫隙問題
- 詳解JavaScript作用域
- bootstrap入門
- 表單驗證(登錄/注冊)
- Bootstrap網格系統
- Bootstrap排版
- Bootstrap創建表單(一)
- Bootstrap表單(二)
- Bootstrap按鈕
- Bootstrap圖片
- Bootstrap字體圖標(glyphicons)
- Bootstrap的aria-label和aria-labelledby
- Bootstrap下拉菜單
- Bootstrap按鈕組
- Bootstrap按鈕菜單
- Bootstrap輸入框組
- Bootstrap導航元素
- Bootstrap導航欄
- sublimeText頻頻崩潰
- JQuery不同版本的差異(checkbox)
- Bootstrap面包屑導航、分頁、標簽、徽章
- Bootstrap警告
- Bootstrap進度條
- 前端的上傳下載
- JS字符串的相關方法
- CSS3選擇器(全)
- CSS3新增文本屬性詳述
- 利用CSS3實現圖片切換特效
- CSS3新增顏色屬性
- CSS3的border-radius屬性詳解
- JS創建對象幾種不同方法詳解
- JS實現繼承的幾種方式詳述(推薦)
- CSS3響應式布局
- JS模塊化開發(requireJS)
- 利用@font-face實現個性化字體
- 前端在html頁面之間傳遞參數的方法
- CSS自動換行、強制不換行、強制斷行、超出顯示省略號
- 如何在Html中引入外部頁面
- reactJS入門
- React組件生命周期
- 使用React實現類似快遞單號查詢效果
- ReactJS組件生命周期詳述
- React 屬性和狀態詳解