對于剛入門的同學,不建議直接用構建工具搭建項目,先從本地引入開始
1.頁面引入文件
結構大致如下
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
// ** Our code goes here! **
</script>
</body>
</html>
其中需要注意,書寫react語法的script
標簽的type
屬性為text/babel
。因為要使用jsx語法,關于jsx,大家可以點擊react系列--jsx
面代碼一共用了三個庫: react.js
、react-dom.js
和 Browser.js
,它們必須首先加載。其中,react.js
是 React 的核心庫,react-dom.js
是提供與 DOM 相關的功能,Browser.js
的作用是將 JSX 語法轉為 JavaScript 語法,這一步很消耗時間,實際上線的時候,應該將它放到服務器完成(babel
模塊)。
2.ReactDOM.render()
ReactDOM.render 是 React 的最基本方法,用于將模板轉為 HTML 語言,并插入指定的 DOM 節點。
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
上面代碼將一個 h1 標題,插入 example 節點
注意:模板必須唯一頂層元素
3.樣式設置
- style
ReactDOM.render(
<div style={{color:'red'}}>
xxxxx
</div>,
document.body
);
- 類名(className)
ReactDOM.render(
<div className="box">content</div>,
document.body
);
4.事件綁定
function say(){
alert("How old are you?")
}
React.render(
<button onClick={say} />,
document.body
);
注意:事件駝峰命名!
5.組件
React 允許將代碼封裝成組件(component),然后像插入普通 HTML 標簽一樣,在網頁中插入這個組件。React.createClass 方法就用于生成一個組件類
var Hello = React.createClass({
render: function() {
return <h1>Hello</h1>;
}
});
ReactDOM.render(
<Hello />,
document.getElementById('app')
);
注意:組件模板必須唯一頂層元素
小插曲(HTML 標簽 vs. React 組件)
ReactDOM.render方法可以渲染HTML結構,也可以渲染React組件。
渲染HTML標簽,聲明變量采用首字母小寫
var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.body);
渲染React組件,聲明變量采用首字母大寫
var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.body);
5.1 組件props
注意:react中props與vue不同,只是作為屬性傳遞,是不可變的
this.props 對象的屬性與組件的屬性一一對應
var Hello = React.createClass({
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<Hello name="veblen"/>,
document.getElementById('app')
);
但是有一個例外,就是 this.props.children
屬性。它表示組件的所有子節點
var NotesList = React.createClass({
render: function() {
return (
<ol>
{
this.props.children.map( function (child) {
return <li>{child}</li>;
})
}
</ol>
);
}
});
ReactDOM.render(
<NotesList>
<span>hello</span>
<span>world</span>
</NotesList>,
document.body
);
這里需要注意,
this.props.children
的值有三種可能:如果當前組件沒有子節點,它就是undefined
;如果有一個子節點,數據類型是object
;如果有多個子節點,數據類型就是array
。所以,處理this.props.children
的時候要小心。
React 提供一個工具方法 React.Children 來處理 this.props.children 。我們可以用 React.Children.map來遍歷子點而不用擔心 this.props.children 的數據類型是 undefined還是 object。更多的 React.Children的方法,請參考官方文檔。
React.Children.map(this.props.children, function (child) {
return <li>{child}</li>;
})
5.2組件PropTypes
組件的屬性可以接受任意值,字符串、對象、函數等等都可以。有時,我們需要一種機制,驗證別人使用組件時,提供的參數是否符合要求。
組件類的PropTypes
屬性,就是用來驗證組件實例的屬性是否符合要求
var MyTitle = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired,
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
上面的Mytitle組件有一個title
屬性。PropTypes
告訴 React,這個 title
屬性是必須的,而且它的值必須是字符串。
如果驗證不通過,則會在控制帶顯示錯誤信息!
getDefaultProps
方法可以用來設置組件屬性的默認值。
var MyTitle = React.createClass({
getDefaultProps : function () {
return {
title : 'Hello World'
};
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
ReactDOM.render(
<MyTitle />,
document.body
);
上面代碼會輸出"Hello World"。
5.3組件內部事件
var Mybtn=React.createClass({
say:function(){
alert("How old are you!")
}
render:function(){
return(
<button onClick={this.say} />
)
}
})
this指向組件實例
5.4組件state
組件免不了要與用戶互動,React 的一大創新,就是將組件看成是一個狀態機,一開始有一個初始狀態,然后用戶互動,導致狀態變化,從而觸發重新渲染 UI
var LikeButton = React.createClass({
getInitialState: function() {
return {liked:true};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? 'love' : 'hate';
return (
<p onClick={this.handleClick}>
I{text}veblen
</p>
);
}
});
ReactDOM.render(
<LikeButton />,
document.getElementById('app')
);
上面代碼是一個LikeButton
組件,它的getInitialState
方法用于定義初始狀態,也就是一個對象,這個對象可以通過 this.state 屬性讀取。當用戶點擊組件,導致狀態變化,this.setState
方法就修改狀態值,每次修改以后,自動調用this.render
方法,再次渲染組件。
由于 this.props
和 this.state
都用于描述組件的特性,可能會產生混淆。一個簡單的區分方法是,this.props
表示那些一旦定義,就不再改變的特性,而this.state
是會隨著用戶互動而產生變化的特性。
5.5組件數據雙向綁定(后期會寫一篇針對數據綁定的文章)
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.body);
5.6組件生命周期
- componentWillMount()----------掛載前
- componentDidMount()-----------掛載后
- componentWillUpdate(object nextProps, object nextState)-----更新前
- componentDidUpdate(object prevProps, object prevState)-----更新后
- componentWillUnmount()-------銷毀前
6.操作真實DOM
組件并不是真實的 DOM 節點,而是存在于內存之中的一種數據結構,叫做虛擬 DOM (virtual DOM)。只有當它插入文檔以后,才會變成真實的 DOM 。根據 React 的設計,所有的 DOM 變動,都先在虛擬 DOM 上發生,然后再將實際發生變動的部分,反映在真實 DOM上,這種算法叫做 DOM diff ,它可以極大提高網頁的性能表現。但是,有時需要從組件獲取真實 DOM 的節點,這時就要用到ref
屬性
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.getElementById('app')
);
上面代碼中,組件MyComponent
的子節點有一個文本輸入框,用于獲取用戶的輸入。這時就必須獲取真實的 DOM 節點,虛擬 DOM 是拿不到用戶輸入的。為了做到這一點,文本輸入框必須有一個 ref
屬性,然后 this.refs.[refName]
就會返回這個真實的 DOM 節點。
需要注意的是,由于 this.refs.[refName]
屬性獲取的是真實 DOM ,所以必須等到虛擬 DOM 插入文檔以后,才能使用這個屬性,否則會報錯。上面代碼中,通過為組件指定 Click 事件的回調函數,確保了只有等到真實 DOM 發生 Click 事件之后,才會讀取this.refs.[refName]
屬性。
7.獲取數據
組件的數據來源,通常是通過 Ajax 請求從服務器獲取,可以使用 componentDidMount
方法(掛載后)設置 Ajax 請求,等到請求成功,再用 this.setState
方法重新渲染 UI
至此,react基本語法結構已介紹完畢,并插入了開發過程中容易出現的問題,加油吧,同學們!