React入門例項參考阮一峰部落格
React 可以在瀏覽器執行,也可以在伺服器執行。伺服器的用法與瀏覽器差別不大。
1 hello world程式
**開發環境**visual studio code和谷歌瀏覽器(谷歌瀏覽器翻牆安裝React Developer Tools)。
1.1 使用 React 開發新專案
前提安裝npm工具,Node版本 >= 6。
在工作空間,執行以下命令:
1. npm install -g create-react-app
2. create-react-app my-app
3. cd my-app
4. npm start
- 1
- 2
- 3
- 4
然後開啟http:// localhost:3000 /檢視您的應用程式。
建立React App不處理後端邏輯或資料庫; 它只是建立一個前端構建管道,所以你可以將它用於任何你想要的後端。
當您準備部署到生產環境時,執行
npm run build
- 1
將在build資料夾中建立應用程式的優化版本。將 src 子目錄的 js 檔案進行語法轉換,轉碼後的檔案全部放在 build 子目錄。
結果
在當前資料夾內建立一個目錄。my-app
在該目錄內,它將生成初始專案結構並安裝依賴項:
my-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ └── favicon.ico
│ └── index.html
│ └── manifest.json
└── src
└── App.css
└── App.js
└── App.test.js
└── index.css
└── index.js
└── logo.svg
└── registerServiceWorker.js
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
沒有配置或複雜的資料夾結構,只有構建應用程式所需的檔案。
安裝完成後,您可以開啟專案資料夾,編輯目錄、檔案開發自己的專案(如下面: 修改APP.js)。
如果您更改了程式碼,該頁面將自動重新載入。您將在控制檯中看到構建錯誤和lint警告。
1) APP.js檔案中編寫Hello world程式
import React, { Component } from `react`;
class App extends Component {
render() {
return (
<div className="App">
<h1 className="App-title">Hello World</h1>
</div>
);
}
}
export default App;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
注意:元件類只能包含一個頂層標籤,否則也會報錯
1.2 執行現有React專案/框架
一般readme檔案中有說明,仔細閱讀。執行現有原始碼包的基本步驟
1) 在專案的目錄安裝依賴
$ npm install
- 1
2) 將src子目錄中的所有jsx檔案轉換為js檔案。
$ npm run build
- 1
- 2
3) 啟動http server
$ node server.js
- 1
2 render()
render()是 React 的最基本方法,用於將模板轉為 HTML 語言,並插入指定的 DOM 節點。
例如:index.js中將App標籤,插入 root節點
ReactDOM.render(
<App />,
document.getElementById(`root`)
);
- 1
- 2
- 3
- 4
3 JSX 語法
HTML 語言直接寫在 JavaScript 語言之中,不加任何引號,這就是 JSX 的語法,它允許 HTML 與 JavaScript 的混寫。
demo2
(專案index.js中修改import App from ‘./demo1’即可執行對應示例)
import React, { Component } from `react`;
var names = [`Alice`, `Emily`, `Kate`];
class App extends Component{
render(){
return(
<div>
{
names.map(function (name, index) {
return <div key={index}>Hello, {name}!</div>
})
}
</div>
)
};
}
export default App;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
JSX 的基本語法規則:遇到 HTML 標籤(以 < 開頭),就用 HTML 規則解析;遇到程式碼塊(以 { 開頭),就用 JavaScript 規則解析。
JSX 允許直接在模板插入 JavaScript 變數。如果這個變數是一個陣列,則會展開這個陣列的所有成員。JSX 會把它的所有成員,新增到模板。
demo03
import React, { Component } from `react`;
var arr = [
<h1>Hello world!</h1>,
<h2>React is awesome</h2>,
];
class App extends Component{
render(){
return(
<div>
<div>{arr}</div>
</div>
)
};
}
export default App;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
4 元件
React 允許將程式碼封裝成元件(component),然後像插入普通 HTML 標籤一樣,在網頁中插入這個元件。class關鍵字用於生成一個元件類。
demo04
import React, { Component } from `react`;
class App extends Component{
render(){
return(
<div>
<HelloMessage name="pengwei" />,
</div>
)
};
}
class HelloMessage extends Component{
render() {
return <h1>Hello {this.props.name}</h1>;
}
}
export default App;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
上面程式碼中,變數 HelloMessage 就是一個元件類。模板插入 時,會自動生成 HelloMessage 的一個例項(下文的”元件”都指元件類的例項)。所有元件類都必須有自己的 render 方法,用於輸出元件。
注意,元件類的第一個字母必須大寫,否則會報錯,比如HelloMessage不能寫成helloMessage。另外,元件類只能包含一個頂層標籤,否則也會報錯。
元件的用法與原生的 HTML 標籤完全一致,可以任意加入屬性,比如 ,就是 HelloMessage 元件加入一個 name 屬性,值為 John。元件的屬性可以在元件類的 this.props 物件上獲取,比如 name 屬性就可以通過 this.props.name 讀取。
注意,新增元件屬性, class 屬性需要寫成 className ,for 屬性需要寫成 htmlFor ,這是因為 class 和 for 是 JavaScript 的保留字。
5 this.props.children
this.props 物件的屬性與元件的屬性一一對應,但是有一個例外,就是 this.props.children 屬性,它表示元件的所有子節點。
demo05
import React, { Component } from `react`;
class App extends Component{
render(){
return(
<div>
<Parent>
<span>hello</span>
<span>world</span>
</Parent>
</div>
)
};
}
class Parent extends Component{
render(){
return(
<ol>
{React.Children.map(this.props.children,function(child)
{return <li>{child}</li>;})}
</ol>
)
};
}
export default App;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
注意, this.props.children 的值有三種可能:如果當前元件沒有子節點,它就是 undefined ;如果有一個子節點,資料型別是 object ;如果有多個子節點,資料型別就是 array 。所以,處理 this.props.children 的時候要小心。
React 提供一個工具方法 React.Children 來處理 this.props.children 。我們可以用 React.Children.map 來遍歷子節點,而不用擔心 this.props.children 的資料型別
6 PropTypes和DefaultProps
元件的屬性可以接受任意值,字串、物件、函式等等都可以。有時,我們需要一種機制,驗證別人使用元件時,提供的引數是否符合要求。
– PropTypes屬性,就是用來驗證元件例項的屬性是否符合要求。
– DefaultProps 方法可以用來設定元件屬性的預設值。
demo06
import React, { Component } from `react`;
import PropTypes from `prop-types`;
class App extends Component{
render(){
return(
<div>
<DefaultMessage />
</div>
);
};
}
class DefaultMessage extends Component{
render() {
return (<h1>Hello {this.props.name}</h1>);
}
}
DefaultMessage.propTypes = {
name: PropTypes.string
};
DefaultMessage.defaultProps ={
name : `World`
}
export default App;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
7 獲取真實的DOM節點
元件並不是真實的 DOM 節點,而是存在於記憶體之中的一種資料結構,叫做虛擬 DOM (virtual DOM)。只有當它插入文件以後,才會變成真實的 DOM 。根據 React 的設計,所有的 DOM 變動,都先在虛擬 DOM 上發生,然後再將實際發生變動的部分,反映在真實 DOM上,這種演算法叫做 DOM diff ,它可以極大提高網頁的效能表現。
但是,有時需要從元件獲取真實 DOM 的節點,這時就要用到 ref 屬性
demo07
import React, { Component } from `react`;
class App extends Component{
render(){
return(
<div>
<TrueDom />
</div>
);
};
}
class TrueDom extends Component{
constructor(props) {
super(props);
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.refs.myTextInput.focus();
};
render() {
return(
<div>
<input type="text" ref="myTextInput" />
<input type="button" value="Focus the text input" onClick={this.handleClick} />
</div>
);
};
}
export default App;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
需要注意的是,由於 this.refs.[refName] 屬性獲取的是真實 DOM ,所以必須等到虛擬 DOM 插入文件以後,才能使用這個屬性,否則會報錯。上面程式碼中,通過為元件指定 Click 事件的回撥函式,確保了只有等到真實 DOM 發生 Click 事件之後,才會讀取 this.refs.[refName] 屬性。
8 this.state
react將元件看成是一個狀態機,一開始有一個初始狀態,然後使用者互動,導致狀態變化,從而觸發重新渲染 UI。
由於 this.props 和 this.state 都用於描述元件的特性,可能會產生混淆。一個簡單的區分方法是,this.props 表示那些一旦定義,就不再改變的特性,而 this.state 是會隨著使用者互動而產生變化的特性
demo08
import React, { Component } from `react`;
class App extends Component{
render(){
return(
<div>
<LikeButton/>
</div>
)
};
}
class LikeButton extends Component{
constructor(props) {
super(props);
this.state = {liked: false};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick(event) {
this.setState({liked: !this.state.liked});
};
render() {
var text = this.state.liked ? `like` : `don`t liked`;
return (
<p onClick={this.handleClick}>
You {text} this. Click to toggle.
</p>
);
};
}
export default App;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
9 表單
使用者在表單填入的內容,屬於使用者跟元件的互動,所以不能用 this.props 讀取
demo9
import React, { Component } from `react`;
class App extends Component{
render(){
return(
<div>
<Input/>
</div>
)
};
}
class Input extends Component{
constructor(props) {
super(props);
this.state = {value: `Hello!`};
// This binding is necessary to make `this` work in the callback
this.handleChange = this.handleChange.bind(this);
};
handleChange(event) {
this.setState({value: event.target.value});
};
render() {
var value = this.state.value;
return (
<div>
<input type="text" value={value} onChange={this.handleChange} />
<p>{value}</p>
</div>
);
};
}
export default App;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
上面程式碼中,文字輸入框的值,不能用 this.props.value 讀取,而要定義一個 onChange 事件的回撥函式,通過 event.target.value 讀取使用者輸入的值。
10 元件的生命週期
元件的生命週期分成三個狀態:
– Mounting:已插入真實 DOM
– Updating:正在被重新渲染
– Unmounting:已移出真實 DOM
React 為每個狀態都提供了兩種處理函式,will 函式在進入狀態之前呼叫,did 函式在進入狀態之後呼叫,三種狀態共計五種處理函式:
– componentWillMount()
– componentDidMount()
– componentWillUpdate(object nextProps, object nextState)
– componentDidUpdate(object prevProps, object prevState)
– componentWillUnmount()
此外,React 還提供兩種特殊狀態的處理函式:
– componentWillReceiveProps(object nextProps):已載入元件收到新的引數時呼叫
– shouldComponentUpdate(object nextProps, object nextState):元件判斷是否重新渲染時呼叫
demo10
import React, { Component } from `react`;
class App extends Component{
render(){
return(
<div>
<ComponentLifestyle name = "pengwei"/>
</div>
)
};
}
class ComponentLifestyle extends Component{
constructor(props) {
super(props);
this.state = {opacity: 1.0};
};
componentWillMount() {
this.timer = setInterval(function () {
var opacity = this.state.opacity;
var flag = this.state.flag;
if(opacity >= 1||opacity<=0)
{flag = !flag;}
if (flag){
opacity -= 0.02;
}
else{
opacity += 0.02;
}
this.setState({
opacity: opacity,
flag: flag
});
}.bind(this), 100);
};
render() {
return (
<div style={{opacity: this.state.opacity}} flag = {true}>
Hello {this.props.name}
</div>
);
};
}
export default App;
原文釋出時間:2018年03月25日
本文來源CSDN部落格如需轉載請緊急聯絡作者
相關文章
- 阮一峰部落格精選
- 阮一峰:為什麼寫部落格?(圖靈訪談)圖靈
- React 入門例項教程React
- React入門學習例項React
- 阮一峰快速排序排序
- React 入門-寫個 TodoList 例項React
- React 入門最好的例項-TodoListReact
- 部落格入門
- [python][flask] Flask 入門(以一個部落格後臺為例)PythonFlask
- 學習React入門最好的例項-TodoListReact
- 值得參考的10個LESSCSS例項CSS
- Jquery入門及例項一jQuery
- react-dva學習 --- 用例項來入門React
- 個人部落格入門4
- 值得參考的10個LESS CSS例項CSS
- socket.io入門示例參考
- 阮一峰每週分享第 2 期
- [翻譯]阮一峰webpack教程(Demo集合)Web
- 阮一峰:curl 網站開發指南網站
- TypeScript入門例項TypeScript
- Websocet 入門例項Web
- SoapUI入門例項UI
- Flutter 入門例項Flutter
- Kafka入門例項Kafka
- Struts入門例項
- 值得學習的技術人——阮一峰
- 觀阮一峰老師js教程筆記JS筆記
- 阮一峰:jQuery官方基礎教程筆記jQuery筆記
- 阮一峰:jQuery的deferred物件詳解jQuery物件
- 阮一峰:Javascript的10個設計缺陷JavaScript
- 阮一峰:學習C語言的教材C語言
- Laravel Nova 入門建立一個簡單的部落格Laravel
- ActiveMQ 入門及例項MQ
- (翻譯)阮一峰老師的webpack使用教程Web
- 阮一峰:論文的版權屬於誰?
- PHP框架Yii系列教程(一):入門例項PHP框架
- SQL快速入門 ( MySQL快速入門, MySQL參考, MySQL快速回顧 )MySql
- 阮一峰關於js同步非同步的解釋JS非同步