做前端的人都知道,目前熱門前端的框架是 VAR = Vue,Anglur,React。 而如果說最熱門的前端框架是誰,毫無懸念是 "React" React 是由 Facebook 主導開發的一個 JavaScript 框架。學習 React 需要你擁有基本 "JavaScript" 和 "HTML ...
做前端的人都知道,目前熱門前端的框架是 VAR => Vue,Anglur,React。
而如果說最熱門的前端框架是誰,毫無懸念是 React
React 是由 Facebook 主導開發的一個 JavaScript 框架。學習 React 需要你擁有基本 JavaScript 和 HTML 知識
接下來讓我們開始學習 React ,首先學習如何使用React輸出一個 Hello React
一、Hello React
新建一個 Reactdemo.html ,輸入以下內容
<!DOCTYPE html>
<html>
<head>
<title>Hello React</title>
<script crossorigin src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script crossorigin src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script crossorigin src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
//我們的React代碼在這裡
ReactDOM.render(
<h1>Hello, React</h1>,
document.getElementById('root')
)
</script>
</body>
</html>
運行試試看!Hello,React!
上面代碼一共用了三個庫:react.js 是 React 的核心庫,react-dom.js 是提供與 DOM 相關的功能,babel.js 的作用是將 JSX 語法轉為 JavaScript 語法。
接下來讓我們看看代碼,在 ReactDOM.render 函數里 我們看到的是一個類似與XML/HTML的語法,但實際上他不是HTML,它就是基於 JavaScript,在 React 當中的一種語法擴展的實現。例如上面JSX語法經過轉換後會變成React創建Element的一個方法。
ReactDOM.render(
React.createElement('h1',null,'Hello, React'),
document.getElementById('root')
)
而 ReactDOM.render 是 React 的最基本方法,用於將模板轉為 HTML 語言,並插入指定的 DOM 節點(例子中是id為root的節點)。
二、JSX語法
JSX 的基本語法規則:遇到 HTML 標簽(以 < 開頭),就用 HTML 規則解析;遇到代碼塊(以 { 開頭),就用 JavaScript 規則解析
JSX表達式
把下麵的代碼運行試試看!
var str = 'cnyballk'
ReactDOM.render(
<h1>Hello, {str}</h1>,
document.getElementById('root')
)
在{}你可以使用任何js表達式,如果str變數是數組,它還會幫你展開,例:
var str = [1,2,3]
ReactDOM.render(
<h1>Hello, {str}</h1>,
document.getElementById('root')
)
JSX嵌套
在JSX里的標簽也可以像 HTML 一樣相互嵌套,需要註意的是,JSX 在嵌套時,最外層有且只能有一個標簽
var str = 'cnyballk'
ReactDOM.render(
<h1>Hello, {str}
<p>我是p元素</p>
</h1>,
document.getElementById('root')
)
如果是這樣就會報錯,所以要註意哦~
var str = 'cnyballk'
ReactDOM.render(
<h1>Hello, {str}</h1>
<p>我是p元素</p>,
document.getElementById('root')
)
三、React組件
React 允許將代碼封裝成組件,然後像插入普通 HTML 標簽一樣,在網頁中插入這個組件,React官方對組件的定義是指在UI界面中,可以被獨立劃分的、可復用的、獨立的模塊。組件從概念上看就像是函數,它可以接收任意的輸入值(稱之為“props”),並返回一個需要在頁面上展示的React元素。
新版本的React里提供了兩種定義組件的方法:
第一種函數定義組件,我們只需要定義一個接收props傳值:
function Hello(props) {
return (<h1>Hello, {props.name}</h1>)
}
第二種是使用ES6的語法,類的概念來定義React組件:
class Hello extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>
}
}
這裡要註意的是組件的首字母必須是大寫,Hello不能寫成hello,否則會報錯。
那麼怎麼使用呢:
ReactDOM.render(
<div>
<Hello name="cnyballk1" />
<Hello name="cnyballk2" />
</div>,
document.getElementById('root')
)
組件內嵌套組件
組件也是可以嵌套組件的,對於React來說,一個網頁就是由不同的組件組合而成,組件互相包含
class Hello extends React.Component{
render (){
return <div>
{
this.props.children.map(function (child) {
return <h1>Hello,{child}</h1>;
})
}
</div>
}
}
class Name extends React.Component{
render(){
return <span>{this.props.name}</span>
}
}
ReactDOM.render(
<Hello>
<Name name="cnyballk1"/>
<Name name="cnyballk2"/>
</Hello>,
document.getElementById('root')
)
是不是很好奇props是什麼?別急,接下來就為你講解
四、Props
props其實就是屬性Properties的縮寫。
組件的屬性可以在組件類的 this.props 對象上獲取,比如 name 屬性就可以通過 this.props.name 讀取
添加組件屬性,有一個地方需要註意,就是 class 屬性需要寫成 className ,for 屬性需要寫成 htmlFor ,這是因為 class 和 for 是 JavaScript 的保留字。
props是只讀的
在React中,props都是自上向下傳遞,從父組件傳入子組件。並且props是只讀的,我們不能在組件中直接修改props的內容。也即是說組件只能根據傳入的props渲染界面,而不能在其內部對props進行修改。
props類型檢查
組件的屬性可以接受任意值,字元串、對象、函數等等。但是有時我們需要一種機制,為了避免錯誤類型的內容傳入,我們可以為props添加類型檢查。
五、State狀態
組件免不了要與用戶互動,而state就好比狀態機,保存著組件的狀態,下麵通過一個計數器的例子來說下state的用法以及需要註意的地方:
class Button extends React.Component{
constructor(props){
super(props)
this.state = {
num:1
}
this.handlerClick = this.handlerClick.bind(this)
}
handlerClick(){
this.setState({num:this.state.num+1})
}
render (){
return <button onClick={this.handlerClick}>{this.state.num}</button>
}
}
ReactDOM.render(
<Button />,
document.getElementById('root')
)
在React中我們通過類定義組件聲明一個有狀態的組件,在構造方法初始化state,之後可以用過this.state來訪問它,初始化state之後,如果我們想改變它,是不可以直接對其賦值的,直接修改state的值沒有任何意義,不會觸發組件的重新渲染。
所以需要this.setState這個方法,在改變state的同時,觸發React內部的一系列函數,最後調用 this.render 方法,再次渲染組件。
六、組件的生命周期
組件有以下生命周期
- componentWillMount
組件即將掛載 - componentWillReceiveProps
組件即將接收props - shouldComponentUpdate
返回是否需要更新組件的判斷 - componentWillUpdate
組件即將更新 - componentDidMount
組件已掛載 - componentDidUpdate
組件已更新 - componentWillUnmount
組件即將卸載
為了更好的方便理解生命周期,讓我們來看看是生命周期是如何流轉的:
class Nums extends React.Component {
constructor(props) {
super(props)
console.log(`子組件構造函數觸發`)
}
componentWillMount() {
console.log(`組件即將掛載`)
}
componentDidMount() {
console.log(`組件已掛載`)
console.log(` `)
}
componentWillReceiveProps(newProps) {
console.log(`組件即將接收props`)
}
componentWillUpdate(nextProps, nextState) {
console.log(`組件即將更新`)
}
componentDidUpdate(prevProps, prevState) {
console.log(`組件更新完畢`)
console.log(` `)
}
componentWillUnmount() {
console.log(`組件即將卸載`)
}
shouldComponentUpdate(newProps, newState) {
console.log(`返回判斷是否要更新組件true`)
return true;
}
render() {
console.log(`組件渲染中`)
return <h1>{ this.props.counter }</h1>
}
}
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
counter: 0
}
console.log(`父組件構造函數觸發`)
console.log('this.state', this.state.counter)
}
upCounter() {
console.log('改變前的counter', this.state.counter)
this.setState((prevState) =>({
counter:(function(){
console.log('改變後的counter', prevState.counter + 1)
return prevState.counter + 1
})()
}))
}
render() {
console.log(`父組件渲染中`)
console.log('準備傳入的counter', this.state.counter)
return (
<div>
<Nums counter={this.state.counter} />
<button onClick={() => this.upCounter()}>+1</button>
<button onClick={() => this.forceUpdate()}> 更新組件</button>
<button onClick={() => {ReactDOM.unmountComponentAtNode(document.getElementById('root'))}}>
卸載組件
</button>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
打開控制台,點擊按鈕,便可以看到我們的生命周期流轉的狀態。
瞭解React組件渲染的流程和原理對我們更深入React非常有幫助,如果你需要發起AJAX來獲取數據渲染,可以放在合適的生命周期里。
總結
React到這裡就結束了,儘管沒有很深入去React,但是如果你認真看了並且去學習,你就已經能夠使用React去寫一些小demo了,如果你有什麼問題,可以留言給我,如果我看到了,我會回覆的。
下次我會更加深入的去講解React