react官網(wǎng):
https://facebook.github.io/react/
內(nèi)容來源:
http://www.ruanyifeng.com/blog/2015/03/react.html
- React 可以在瀏覽器運行,也可以在服務(wù)器運行
一、react網(wǎng)頁源碼(html模板)
<! DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
//React核心庫
<script src="../build/react-dom.js"></script>
//提供與 DOM 相關(guān)的功能
<script src="../build/browser.min.js"></script>
//將 JSX 語法轉(zhuǎn)為 JavaScript 語法
//以上3個必須首先加載
</head>
<body>
<div id="example"></div>
//type屬性為text/babel,因為react有自己的JSX語法,與javascript不兼容。凡使用JSX的地方,都要用 type="text/babel"
<script type="text/babel">
// ** 代碼開始地方 **
</script>
</body>
</html>
二、模板轉(zhuǎn)html語言
ReactDOM.render用于將模板轉(zhuǎn)為 HTML ,并插入d到指定 DOM 節(jié)點中。
ReactDOM.render(
<h1>Hello, react</h1>,
document.getElementById('example')
);
有2個參數(shù):
ReactDOM.render(
模板,
插入位置
);
三、JSX語法
- 1、JSX語法規(guī)則:遇到html標簽(以<開頭)用html語法解析,遇到代碼塊(以{開頭)用js解析
var itnames = ['react','html','css'];
ReactDOM.render(
<div>
{
itnames.map(function (name) {
return <p>hello, {name}</p>
})
}
</div>,
document.getElementById('example')
);

Paste_Image.png
- 2、JSX允許直接在模板插入js變量,若變量是一個數(shù)組,則會展開顯示數(shù)組所有元素
var arr = [
<h1>Hello world!</h1>,
<h2>React is awesome</h2>,
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('example')
);

Paste_Image.png
四、組件
React.createClass()方法:生成一個組件
var HelloMessage = React.createClass({
render: function () {
return <h1>hello {this.props.name} {this.props.className}</h1>;
}
});
ReactDOM.render(
<HelloMessage name="wy" className="ceshjo"/>,
document.getElementById('example')
);
注意:
- 組件類的第一個字母必須大寫
- 組件類只能包含一個頂層標簽
- 組件的屬性可以在組件類的 this.props 對象上獲取
- class 屬性需寫成 className ,for 屬性需寫成 htmlFor ,因為 class 和 for 是 JavaScript 的保留字。
五、this.props.children
表示組件的所有子節(jié)點
返回的值有3種:(注意處理)
- undefined 組件沒有子節(jié)點
- object 組件只有一個子節(jié)點
- array 組件有多個子節(jié)點
用React.Children.map 來遍歷子節(jié)點,就無需考慮上述問題
var NotesList = React.createClass({
render: function() {
return (
<ol>
{
/// this.props.children.map(function (child) {
React.Children.map(this.props.children, function (child) {
return <li>{child}</li>;
})
}
</ol>
);
}
});
ReactDOM.render(
<NotesList>
<span>hello</span>//組件的子節(jié)點
<span>world</span>
</NotesList>,
document.getElementById('example')
);

Paste_Image.png
六、PropTypes
用來驗證組件實例的屬性是否符合要求
var data = 123;
var MyTitle = React.createClass({
propTypes: {
//title屬性是必須的,且它的值必須是字符串
title: React.PropTypes.string.isRequired,
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
ReactDOM.render(
<MyTitle title={data} />,
document.getElementById('example')
);
上述代碼就會打印出警告

Paste_Image.png
getDefaultProps用來設(shè)置組件屬性的默認值
var MyTitle = React.createClass({
getDefaultProps : function () {
return {
title : 'Hello World'
};
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
ReactDOM.render(
<MyTitle />,
document.body
);
七、獲取真實的DOM節(jié)點
組件不是真實的DOM節(jié)點,而是存在于內(nèi)存中的一種數(shù)據(jù)結(jié)構(gòu),即虛擬DOM。
只有將其插入文檔之后,才會成為真實的DOM。
react中,所有DOM的變動都先在虛擬DOM上發(fā)生,然后再將實際發(fā)生變動的部分反映在真實DOM上。(提高性能)
ref屬性:
var MyComponent = React.createClass({
handleClick: function() {
//this.refs.[refName] 獲取真實的DOM節(jié)點
this.refs.myTextInput.focus();
},
render: function() {
return (
<div>
<input type="text" ref="myTextInput" />
<input type="button" value="輸入框獲得焦點" onClick={this.handleClick} />
</div>
);
}
});
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);
注意:
- 必須等到虛擬 DOM 插入文檔以后,才能使用這個this.refs.[refName]屬性
八、this.state
將組件看成一個狀態(tài)機,一開始有一個初始狀態(tài),然后用戶互動導(dǎo)致狀態(tài)變化,從而觸發(fā)重新渲染UI
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 liked';
return (
<p onClick={this.handleClick}>
You {text}.
</p>
);
}
});
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
- getInitialState:定義初始化狀態(tài),是一個對象,可以通過this.state讀取
- this.setState:修改狀態(tài)值,自動調(diào)用render再次渲染組件
九、表單
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.getElementById('example'));
定義一個 onChange 事件的回調(diào)函數(shù),通過
event.target.value 讀取用戶輸入的值,textarea 元素、select元素、radio元素都屬于這種情況
十、組件的生命周期
3個狀態(tài)
- 1、Mounting:已插入真實 DOM
- 2、Updating:正在被重新渲染
- 3、Unmounting:已移出真實 DOM
每個狀態(tài)有兩種處理函數(shù)
- will 函數(shù)在進入狀態(tài)之前調(diào)用
- did 函數(shù)在進入狀態(tài)之后調(diào)用
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()
componentWillReceiveProps(object nextProps)
//已加載組件收到新的參數(shù)時調(diào)用
shouldComponentUpdate(object nextProps, object nextState)
//組件判斷是否重新渲染時調(diào)用
示例:
var Hello = React.createClass({
getInitialState: function () {
return {
opacity: 1.0
};
},
componentDidMount: function () {
this.timer = setInterval(function () {
var opacity = this.state.opacity;
opacity -= .05;
if (opacity < 0.1) {
opacity = 1.0;
}
this.setState({
opacity: opacity
});
}.bind(this), 100);
},
render: function () {
return (
// 第一個{}表示這是javascript,第二個{}表示樣式對象
<div style={{opacity: this.state.opacity}}>
Hello {this.props.name}
</div>
);
}
});
ReactDOM.render(
<Hello name="world"/>,
document.getElementById('example')
);
十一、ajax
組件的數(shù)據(jù)來源,通常是通過 Ajax 請求從服務(wù)器獲??;
用 componentDidMount 方法設(shè)置 Ajax 請求;
等到請求成功,再用 this.setState 方法重新渲染 UI
var UserGist = React.createClass({
getInitialState: function() {
return {
username: '',
lastGistUrl: ''
};
},
componentDidMount: function() {
// (請求接口地址,回調(diào)函數(shù))
$.get(this.props.source, function(result) {
var lastGist = result[0]; //result 結(jié)果列表
if (this.isMounted()) {
this.setState({
username: lastGist.owner.login,
lastGistUrl: lastGist.html_url
});
}
}.bind(this));
},
render: function() {
return (
<div>
{this.state.username}'s last gist is <a href={this.state.lastGistUrl}>here</a>.
</div>
);
}
});
ReactDOM.render(
<UserGist source="請求接口地址" />,
document.getElementById('example')
);