react.js總結學習
React jsx 語法
React 使用jsx來替代javascript語法。
實際上html語言直接寫在javaScript語言中,這就是jsx語法,而且不加任何引號。屬於javascript的語法變數使用 {} 表示。
入門例項:
<!DOCTYPE html> <html> <head> <title></title> <script src="react-15.3.1/build/react.min.js"></script> <script src="react-15.3.1/build/react-dom.min.js"></script> <script src="react-15.3.1/build/browser.min.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> ReactDOM.render( <h2>Hello,world</h2>, document.getElementById('example') ) </script> </body> </html>
這裡的type型別要注意了,不再是 “ text/javascript” 而是: text/babel 。因為使用的是jsx的語法,所以這裡必須新增。
使用到的一個庫:browser ,這個庫是將jsx語法轉換成javascript語法。
ReactDOM.render()是React的最基本方法,用於將模版轉換為html語言,並插入到指定的模板節點中。
ReactDOM.render(
<h2>Hello,world</h2>,
document.getElementById('example')
)
上邊是將h2標籤插入到example節點中。
獨立檔案的引入
比如一個外部的react.js程式碼要引入到裡面來。
<body>
<div id="example"></div>
<script type="text/babel" src="helloworld_react.js"></script>
</body>
語法內部的註釋
{/*註釋*/}
例如:
ReactDOM.render(
<h2>Hello,world</h2>,
{/*註釋*/}
document.getElementById('example')
)
插入陣列:
<script type="text/babel"> var arr = [ <h3>xixi</h3>, <h3>haha</h3> ]; ReactDOM.render( <h2>{arr}</h2>, document.getElementById('example0') ) </script>
例項二
<script type="text/babel">
var arr = ['alice','emily','kate'];
ReactDOM.render(
<div>
{
arr.map(function(name){
return <div>Hello,{name}</div>
})
}
</div>
,
document.getElementById('example0')
);
</script>
使用樣式:
<script type="text/babel">
var myStyle = {
fontSize:20,
color:'#FF0000'
};
ReactDOM.render(
<div>
<h1 style={myStyle}> w3cschool</h1>
<h2>歡迎學習 React</h2>
</div>
,
document.getElementById('example')
);
</script>
元件:
React 因為有了元件,開發的效率才會非常的高 ,因為元件的複用效能非常的好,元件封裝好了後 ,就像html普通的標籤一樣,可以進行插入這個元件。
生成一個元件使用React.createClass
例如:
<script type="text/babel">
var HelloMessage = React.createClass({
render(){
return (<h1>Hello World! {this.props.name}</h1>);
}
});
ReactDOM.render(
<HelloMessage name="xixihaha"/>,
document.getElementById('example1')
)
</script>
注意:
所有的元件必須要有自己的render方法。
在ReactDOM.render()方法中,內部的兩條語句之間必須是一個逗號。
元件的引用變數必須是大寫字母開頭 ,如果用小寫字母開頭,會報錯。
上邊的元件添加了一個屬性 ,name=xixihaha
這個屬性,會傳遞到元件物件中,使用 this.props.name就可以讀取到元件的屬性值。
組合元件
就是將多個元件組合起來。
<script type="text/babel">
var WebSite = React.createClass({
render(){
return(
<div>
<Name name={this.props.name}/>
<Link site={this.props.site}/>
</div>
)
}
});
var Name = React.createClass({
render(){
return(
<h1>{this.props.name}</h1>
)
}
});
var Link = React.createClass({
render(){
return(
<a href={this.props.site} target="_black">{this.props.site}</a>
)
}
});
ReactDOM.render(
<WebSite name="w3cschool" site="https://www.baidu.com"/>,
document.getElementById('example2')
)
</script>
this.state
React 把元件看成是一個狀態機(State Machines)。通過與使用者的互動,實現不同狀態,然後渲染 UI,讓使用者介面和資料保持一致。
React 裡,只需更新元件的 state,然後根據新的 state 重新渲染使用者介面(不要操作 DOM).
一開始有一個初始狀態,然後使用者互動,導致狀態變化,從而觸發重新渲染 UI .
<script type="text/babel">
var LikeButton = React.createClass({
getInitialState(){
return {liked:false};
},
handleClick(event){
this.setState({liked:!this.state.liked});
},
render(){
var text = this.state.liked ? "喜歡" : "不喜歡";
return(
<p onClick={this.handleClick}>
你<b>{text}</b>點我切換狀態
</p>
)
}
});
ReactDOM.render(
<LikeButton/>,
document.getElementById('example3')
)
</script>
在定義元件時,方法和方法之間必須使用逗號隔開 。
初始化:
getInitialState(){
return {liked:false};
},
在return方法中可以使用多個屬性:
return {
liked:false,
xiix:"",
isshow:true,
};
this.props
state 和 props 主要的區別在於 props 是不可變的,而 state 可以根據與使用者互動來改變。這就是為什麼有些容器元件需要定義 state 來更新和修改資料。 而子元件只能通過 state 來傳遞資料。
<div id="example4"></div>
<script type="text/babel">
var MyTitle = React.createClass({
render(){
return <h1>{this.props.title}</h1>;
},
});
ReactDOM.render(
<MyTitle title="title"/>,
document.getElementById('example4')
)
</script>
預設的props
當不給props設定引數時,可以設定一個預設的值。
通過getDefaultProps()方法。
<script type="text/babel">
var MyTitle = React.createClass({
getDefaultProps(){
return{
title:'title'
}
},
render(){
return <h1>{this.props.title}</h1>;
},
});
ReactDOM.render(
<MyTitle/>,
document.getElementById('example4')
)
</script>
state和props一起使用
<script type="text/babel">
var WebSite = React.createClass({
getInitialState(){
return{
name:"title",
site:'https://www.baidu.com'
}
},
render(){
return(
<div>
<Name name={this.state.name}/>
<Link site={this.state.site}/>
</div>
)
}
});
var Name = React.createClass({
render(){
return(
<h1>{this.props.name}</h1>
)
}
});
var Link = React.createClass({
render(){
return(
<a href={this.props.site} target="_black">{this.props.site}</a>
)
}
});
ReactDOM.render(
<WebSite/>,
document.getElementById('example2')
)
</script>
Props驗證
元件的屬性可以接受任意值,字串、物件、函式等等都可以。有時,我們需要一種機制,驗證別人使用元件時,提供的引數是否符合要求。
元件類的PropTypes屬性,就是用來驗證元件例項的屬性是否符合要求。
Props 驗證使用 propTypes,它可以保證我們的應用元件被正確使用,React.PropTypes 提供很多驗證器 (validator) 來驗證傳入資料是否有效。當向 props 傳入無效資料時,JavaScript 控制檯會丟擲警告。
<script type="text/babel">
var MyTitle = React.createClass({
propTypes:{
title:React.PropTypes.string.isRequired,
},
render(){
return <h1>{this.props.title}</h1>;
},
});
ReactDOM.render(
<MyTitle title="react js學習"/>,
document.getElementById('example4')
)
</script>
可選的基本型別:
propTypes: {
// 可以宣告 prop 為指定的 JS 基本資料型別,預設情況,這些資料是可選的
optionalArray: React.PropTypes.array,
optionalBool: React.PropTypes.bool,
optionalFunc: React.PropTypes.func,
optionalNumber: React.PropTypes.number,
optionalObject: React.PropTypes.object,
optionalString: React.PropTypes.string,
}
React 元件生命週期
元件的生命週期可分成三個狀態:
Mounting:已插入真實 DOM
Updating:正在被重新渲染
Unmounting:已移出真實 DOM
生命週期方法有:
componentWillMount 在渲染前呼叫,在客戶端也在服務端。
componentDidMount : 在第一次渲染後呼叫,只在客戶端。之後元件已經生成了對應的DOM結構,可以通過this.getDOMNode()來進行訪問。 如果你想和其他JavaScript框架一起使用,可以在這個方法中呼叫setTimeout, setInterval或者傳送AJAX請求等操作(防止異部操作阻塞UI)。
componentWillReceiveProps 在元件接收到一個新的prop時被呼叫。這個方法在初始化render時不會被呼叫。
shouldComponentUpdate 返回一個布林值。在元件接收到新的props或者state時被呼叫。在初始化時或者使用forceUpdate時不被呼叫。 可以在你確認不需要更新元件時使用。
componentWillUpdate在元件接收到新的props或者state但還沒有render時被呼叫。在初始化時不會被呼叫。
componentDidUpdate 在元件完成更新後立即呼叫。在初始化時不會被呼叫。
componentWillUnmount在元件從 DOM 中移除的時候立刻被呼叫。
<script type="text/babel">
var Hello = React.createClass({
getInitialState(){
return{
opacity:1.0
}
},
componentDidMount(){
this.timer = setInterval(function(){
var opacity = this.state.opacity;
opacity -= 0.05;
if(opacity < 0.1){
opacity = 1.0 ;
}
this.setState({
opacity:opacity
})
}.bind(this),100);
},
render(){
return (
<div style={{opacity:this.state.opacity}}>
hello {this.props.name}
</div>
)
}
});
ReactDOM.render(
<Hello name="world"/>,
document.getElementById('example5')
)
</script>
React AJAX
React 元件的資料可以通過 componentDidMount 方法中的 Ajax 來獲取,當從服務端獲取資料庫可以將資料儲存在 state 中,再用 this.setState 方法重新渲染 UI。
當使用非同步載入資料時,在元件解除安裝前使用 componentWillUnmount 來取消未完成的請求。
<script type="text/babel">
var UserGist = React.createClass({
getInitialState(){
return {
username:'',
lastGistUrl:''
}
},
componentDidMount(){
this.serverRequest = $.get(this.props.source,function(result){
var lastGist = result[0];
this.setState({
username:lastGist.owner.login,
lastGistUrl:lastGist.owner.html_url
});
}.bind(this));
},
componentWillUnMount(){
this.serverRequest.abort();
},
render(){
return(
<div>
{this.state.username}使用者最新的 Gist 共享地址:
<a href={this.state.lastGistUrl}>
{this.state.lastGistUrl}
</a>
</div>
)
}
});
ReactDOM.render(
<UserGist source="https://api.github.com/users/octocat/gists"/>,
document.getElementById('example8')
)
</script>
這裡的非同步請求使用的是jquery
ref屬性
React 支援一種非常特殊的屬性 Ref ,你可以用來繫結到 render() 輸出的任何元件上。
這個特殊的屬性允許你引用 render() 返回的相應的支撐例項( backing instance )。這樣就可以確保在任何時間總是拿到正確的例項。
元件並不是真實的 DOM 節點,而是存在於記憶體之中的一種資料結構,叫做虛擬 DOM (virtual DOM)。只有當它插入文件以後,才會變成真實的 DOM 。根據 React 的設計,所有的 DOM 變動,都先在虛擬 DOM 上發生,然後再將實際發生變動的部分,反映在真實 DOM上,這種演算法叫做 DOM diff ,它可以極大提高網頁的效能表現。
但是,有時需要從元件獲取真實 DOM 的節點,這時就要用到 ref 屬性。
<script type="text/babel">
var MyComponent = React.createClass({
handleClick(){
this.refs.myinput.focus();
},
render(){
return (
<div>
<input type="text" ref="myinput"/>
<input type="button"
value="點選我輸入框獲取焦點"
onClick={this.handleClick}
/>
</div>
)
}
})
ReactDOM.render(
<MyComponent/>,
document.getElementById('example6')
)
</script>