網址收藏: React官網,React的Github,React的中文文件
1.react是什麼?
React起源於Facebook的內部專案,因為該公司對市場上所有的Javascript MVC框架都不滿意,決定自己寫一套,用來架設Instargm的網站。做完以後,發現很好用,就在2013年5月開源。
2.安裝react
- 全域性安裝react腳手架工具
npm install create-react-app -g
- 安裝阮一峰老師的教程
git clone git@github.com:ruanyf/react-demos.git
下載下來
3.react特性
重點:元件,狀態
核心: 狀態
4.語法。
4.1 html模板
<!DOCTYPE html>
<html>
<head>
<!-- 這是核心js -->
<script src="../build/react.js"></script>
<!-- 這是處理虛擬dom相關的js -->
<script src="../build/react-dom.js"></script>
<!-- 這是把JSX語法轉換為js語法 (注意:JSX就是可以把html寫在js裡面。) -->
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<!-- 這裡加type就是告訴遊覽器,這裡使用的是JSX語法模板。 -->
<script type="text/babel">
//這裡寫
</script>
</body>
</html>
4.2 ReactDOM.render()
React最基本的方法,用於把模板轉換成html語言,並且插入指定的節點。
例如:
ReactDOM.render(
<h2>Welcome to React World!</h2>,
document.getElementById(`myapp`)
)
4.3 JSX語法
JSX是可以在js中寫html,遇到html標籤(例如:
<
)就用html
解析,遇到程式碼塊(例如:{
)就用javascript規則解析。
例如:
<!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="example"></div>
<div id="food"></div>
<script type="text/babel">
var names = [`Alice`, `Emily`, `Kate`];
var foods = [`meal`,`sala`,`milk`];
ReactDOM.render(
<div>
{
names.map(function (name, index) {
return <div key={index}>Hello, {name}!</div>
})
}
</div>,
document.getElementById(`example`)
);
ReactDOM.render(
<div>
{
foods.map(function (food, index) {
return <div key={index}>I like eat {food}!</div>
})
}
</div>,
document.getElementById(`food`)
)
</script>
</body>
</html>
4.4 元件 React.createClass()
React允許將程式碼封裝成元件(component),然後把它當成html標籤插入到網頁中。React.createClass()就是可以建立一個組建類。
例如:
<!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="foods"></div>
<script type="text/babel">
var LikeFood = React.createClass({ //建立元件類
render: function() {
return <p>I like eat <mark>{this.props.name}</mark></p>;
}
});
ReactDOM.render(
<LikeFood name="Apple"/>,
document.getElementById(`foods`)
)
</script>
</body>
</html>
4.5 this.props.children
this.props
物件的屬性與元件的屬性基本上是一致的,特殊在於this.props.children
屬性,它表示元件的所有子節點。
注意: this.props.children
有三個可能,如果當前元件沒有子節點,就是顯示undefined
;如果有一個子節點,資料型別就是object
;如果有多個子節點,就是array
,所以要小心。
但React提供了一個方法遍歷所有子節點,React.Children
,通過this.props.children
來遍歷。
<!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="foods"></div>
<script type="text/babel">
var FoodList = React.createClass({
render: function() {
return (
<ul>
{
React.Children.map(this.props.children,function (child) {
return <li>{child}</li>;
})
}
</ul>
)
}
})
ReactDOM.render(
<FoodList>
<span>Hello,</span>
<span>I like eat</span>
<span>Apple!</span>
</FoodList>,
document.getElementById(`foods`)
)
</script>
</body>
</html>
4.6 PropTypes
元件的屬性可以接受任何值,如字串,數字,陣列,物件,函式,但是需要一種機制來驗證使用元件提供的引數是否符合要求,PropTypes就是用來驗證這個的。
<!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="foods"></div>
<script type="text/babel">
var str = 123;
var MyNum = React.createClass({
propTypes: {
num: React.PropTypes.number.isRequired,
},
render: function() {
return <h2>{this.props.num}</h2>
}
});
ReactDOM.render(
<MyNum num={str} />,
document.getElementById(`foods`)
)
</script>
</body>
</html>
補充:還可以新增預設值。`
getDefaultProps: function() {
return {
num: 1818
}
}
例如:
<!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="foods"></div>
<script type="text/babel">
var str;
var MyNum = React.createClass({
getDefaultProps: function() {
return {
num: 1818
}
}
propTypes: {
num: React.PropTypes.number.isRequired,
},
render: function() {
return <h2>{this.props.num}</h2>
}
});
ReactDOM.render(
<MyNum num={str} />,
document.getElementById(`foods`)
)
</script>
</body>
</html>
4.7 獲取真實的DOM節點
元件並不是真的dom節點,只是存在記憶體中的資料結構,叫做虛擬DOM(virtual)。當它插入到文件以後,才會變成真實的DOM。
所有的DOM變動,先是在虛擬DOM上發生變動,然後再在實際發生變動的部分,反映在真實的DOM,這種叫做DOM diff,它可以極大提高網頁的效能表現。
有時需要從元件獲取真實的DOM的節點,這個時候就要用到ref
屬性。
注意:React還支援許多事件,更多請訪問事件。
例如:
<!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="foods"></div>
<script type="text/babel">
var MyFoods = React.createClass({
showContent: function() {
this.refs.myFoodInput.focus();
},
render: function() {
return (
<div>
<input type="text" ref="myFoodInput" />
<input type="button" value="自動聚焦" onClick={this.showContent} />
</div>
)
}
})
ReactDOM.render(
<MyFoods />,
document.getElementById(`foods`)
)
</script>
</body>
</html>
4.8 this.state 狀態管理
元件免不了要和使用者互動,React的一大創新就是把元件看成是一個狀態機,一開始有個初始狀態,然後使用者互動,導致狀態變化,從而重新出發渲染UI。
注意: getInitialState
方法用於定義初始狀態,但同時它是一個物件,這個可以通過this.state
屬性讀取。
當使用者點選元件,導致狀態發生變化,this.setState
方法就會修改狀態值,每次修改完,會自動呼叫this.render
方法,再次渲染元件。
this.props
和this.state
都是描述元件的特性,但是不同的是this.props
是指一旦定義好了,就不再發生變化的特性,而this.state
是會隨著使用者互動而產生變化的特性。
例如:
<!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="foods"></div>
<script type="text/babel">
var FoodButton = React.createClass({
getInitialState: function() {
return {food: false};
},
callClick: function(event) {
this.setState({food: !this.state.food});
},
render: function() {
var text1 = this.state.food ? `like eat apple` : `hate eat apple`;
return (
<p onClick={this.callClick}>
You {text1}!
</p>
);
}
});
ReactDOM.render(
<FoodButton />,
document.getElementById(`foods`)
)
</script>
</body>
</html>
4.9 表單
使用者在表單填入的內容,屬於使用者和元件之間的互動,所以不能用
this.state
,而要定義一個onChange
事件的回撥函式,通過event.target.value
讀取使用者的值。
注意:textarea
,select
,radio
都屬於這種情況。
例如:
<!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="food"></div>
<script type="text/babel">
var Food = React.createClass({
getInitialState: function() {
return {val: `Welcome to React!`};
},
hanChange: function(event) {
this.setState({val:event.target.value});
},
render: function() {
var val = this.state.val;
return (
<div>
<input type="text" value={val} onChange={this.hanChange} />
<p>{val}</p>
</div>
);
}
})
ReactDOM.render(<Food />,document.getElementById(`food`))
</script>
</body>
</html>
4.10 元件的生命週期
React中元件的生命週期分為三個狀態,Mounting是已經插入真實DOM,Updating是正在被重新渲染,Unmounting是已移出真實DOM。
每個狀態都有兩種處理函式,will函式是進入狀態之前,did函式是進入狀態之後,三種狀態共計五種函式。
注意:元件的樣式style不能寫成<div style={opacity: this.state.opacity}>
,要寫成<div style={{opacity: this.state.opacity}}>
。
因為React元件樣式是個物件,所以第一個大括號表示Javascript語法,第二個大括號表示樣式物件。
五種函式
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentWillUpdate(object prevState, object prevState)
componentWillUnMount()
例如:第二種,在已插入真實DOM之後觸發。
<!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="food"></div>
<script type="text/babel">
var Food = React.createClass({
getInitialState: function() {
return {
opacity: 0
}
},
componentDidMount: function() {
this.timer = setInterval(function() {
var opacity = this.state.opacity;
opacity += .05;
if (opacity > 1) {
opacity = 0;
}
this.setState({
opacity: opacity
})
}.bind(this),100);
},
render: function() {
return (
<div style={{opacity: this.state.opacity}}>
Hello, {this.props.title}
</div>
);
}
});
ReactDOM.render(
<Food title="apple"/>,
document.getElementById(`food`)
)
</script>
</body>
</html>
4.11 Ajax的使用
元件的資料來源一般都是通過Ajax請求從伺服器獲取,可以使用
componentDidMount()
方法設定Ajax請求,等到請求成功,再用this.setState
方法重新渲染UI。
例如:
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
<script src="../build/jquery.min.js"></script>
</head>
<body>
<div id="food"></div>
<script type="text/babel">
var ClientGits = React.createClass({
getInitialState: function() {
return {
id: ``,
addr: ``
};
},
componentDidMount: function() {
$.get(this.props.source,function (result) {
var gits = result[0];
this.setState({
id: gits.id,
addr: gits.git_pull_url
});
}.bind(this));
},
render: function() {
return (
<div>
UserId is <a href=`#userId`>{this.state.id}</a>, Git Address is <a href={this.state.addr}>{this.state.addr}</a>!
</div>
);
}
});
ReactDOM.render(
<ClientGits source="https://api.github.com/users/octocat/gists" />,
document.getElementById(`food`)
)
</script>
</body>
</html>
注意:上面採用了jquery的Ajax,還可以採用其他的庫。我們甚至可以把Promise物件傳入元件。
例如:
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
<script src="../build/jquery.min.js"></script>
</head>
<body>
<div id="projects"></div>
<script type="text/babel">
var Projects = React.createClass({
getInitialState: function() {
return {
loading: true,
error: null,
data: null
};
},
componentDidMount() {
this.props.promise.then(
value => this.setState({loading: false, data: value}),
error => this.setState({loading: false, error: error})
)
},
render: function() {
if (this.state.loading) {
return <span>Loading...</span>;
} else if (this.state.error != null) {
return <span>Error:{this.state.error.message}</span>;
} else {
var res = this.state.data.items;
var resList = res.map(function (res,index) {
return (
<li key={index}><a href={res.html_url} target="_blank">{res.name}</a>({res.stargazers_count} stars)<br/>{res.description}</li>
);
});
return (
<main>
<h1>Github上最受歡迎的JS專案</h1>
<ul>{resList}</ul>
</main>
);
}
}
});
ReactDOM.render(
<Projects promise={$.getJSON(`https://api.github.com/search/repositories?q=javascript&sort=stars`)} />,
document.getElementById(`projects`)
)
</script>
</body>
</html>