范例說明
接下來我們要通過一個(gè)簡(jiǎn)單的案例覆劈,詳細(xì)的學(xué)習(xí)React的內(nèi)容
如上圖所示,兩個(gè)按鈕沛励,點(diǎn)擊加號(hào)按鈕责语,數(shù)字加一,點(diǎn)擊減號(hào)按鈕侯勉,數(shù)字減一
代碼結(jié)構(gòu)
使用
create-react-app
創(chuàng)建一個(gè)工程,將其中的代碼結(jié)構(gòu)刪減到最簡(jiǎn)單的模式
修改index.js
index.js
中的代碼就很簡(jiǎn)單了铝阐,只要引入App組件址貌,執(zhí)行渲染即可
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App'
ReactDOM.render(<App/>, document.getElementById('root'));
組件的基本內(nèi)容
App.js
中的內(nèi)容才是我們要真正實(shí)現(xiàn)的邏輯,我們將使用ES6的方式創(chuàng)建一個(gè)React的組件,步驟如下
- 引入react
import React from 'react'
2.創(chuàng)建組件徘键,并讓組件繼承
React.Component
,同時(shí)實(shí)現(xiàn)render函數(shù)
class App extends React.Component{
render(){
return (
<div>
</div>
)
}
}
3.為組件指定默認(rèn)輸出
export default App
完整代碼如下:
import React from 'react';
class App extends React.Component{
render(){
return (
<div>
</div>
)
}
}
export default App;
-
React.Component
是react的一個(gè)抽象基類练对,單獨(dú)引用它毫無意義,我們通常用其來實(shí)現(xiàn)子類吹害,實(shí)現(xiàn)子類的時(shí)候必須要實(shí)現(xiàn)其render函數(shù) - render函數(shù)的所用是返回組件的內(nèi)容螟凭,而渲染的過程是有 react框架來完成的,在
return()
中只能有一個(gè)頂級(jí)的標(biāo)簽元素 -
export default
指定了當(dāng)前組件輸出的默認(rèn)模塊
功能實(shí)現(xiàn)
范例中的內(nèi)容可分為四個(gè)部分
1.加號(hào)按鈕
2.減號(hào)按鈕
3.簡(jiǎn)單文本
4.鼠標(biāo)點(diǎn)擊按鈕變化的數(shù)字
其中按鈕和文本都非常簡(jiǎn)單它呀,但是數(shù)字需要鼠標(biāo)點(diǎn)擊進(jìn)行改變的螺男,假如我們沒有學(xué)習(xí)過任何的前端框架棒厘,我們就要使用document對(duì)象,獲取頁面的內(nèi)容下隧,然后將其裝換為數(shù)字奢人,再對(duì)數(shù)字進(jìn)行計(jì)劃,然后將計(jì)算結(jié)果寫入頁面淆院。而使用react來實(shí)現(xiàn)何乎,我們需要知道,react的核心目標(biāo) 組件化土辩,組件中可變換的內(nèi)容稱之為狀態(tài)
組件中的數(shù)據(jù)來源有兩種支救,內(nèi)部聲明和外部傳入,分別用state和prop進(jìn)行區(qū)別和表示拷淘,在es6組件中各墨,可以通過constructor
構(gòu)造函數(shù)中接收外部傳來的prop和聲明內(nèi)部使用的狀態(tài)數(shù)據(jù),在本文的范例中辕棚,我們需要用到一個(gè)在鼠標(biāo)點(diǎn)擊后不斷變化的數(shù)字
constructor(props){
super(props);
this.state = {
count:0
}
}
我們已經(jīng)聲明了內(nèi)部狀態(tài)欲主,并接收了外部傳入的數(shù)組,下面我實(shí)現(xiàn)頁面的展示內(nèi)容,即實(shí)現(xiàn)render函數(shù)中的內(nèi)容
render(){
return (
<div>
<button>+</button>
<button>+</button>
<span>當(dāng)前點(diǎn)擊次數(shù)</span>
<span>{this.state.count}</span>
</div>
)
}
渲染效果如圖1-3所示
內(nèi)容美化
從頁面效果來看逝嚎,各個(gè)元素緊靠在一起扁瓢,不太好看,我們通過簡(jiǎn)單的css對(duì)其進(jìn)行美化补君,要達(dá)到的目標(biāo)是:
- 整個(gè)內(nèi)容增加上邊距和左邊距
- 按鈕引几、文本、數(shù)字相互之間有一定的間距
在react中挽铁,使用css的方式與傳統(tǒng)的方式有不同的地方
- 引入外部樣式文件
新建style/App.css
.box{
margin-left: 50px;
margin-top: 50px;
}
.box *{
margin:auto 5px;
}
在App.js引入這個(gè)css文件
import '../style/App.css'
在這里要值得注意的是伟桅,在react中,class屬性要寫成className叽掘,因?yàn)閏lass是 JavaScript 的保留字
render(){
return (
<div className="box">
<button>+</button>
<button>-</button>
<span>當(dāng)前點(diǎn)擊次數(shù)</span>
<span>{this.state.count}</span>
</div>
)
}
- 使用JavaScript對(duì)象來聲明樣式
render(){
const style={
marginLeft:'50px',
marginTop:'50px'
}
const item = {
margin:'auto 5px'
}
return (
<div style={style}>
<button style={item}>+</button>
<button style={item}>-</button>
<span style={item}>當(dāng)前點(diǎn)擊次數(shù)</span>
<span style={item}>{this.state.count}</span>
</div>
)
}
運(yùn)行效果與圖1-4一樣
使用對(duì)象聲明樣式時(shí)楣铁,要使用
camelCase
,也就是駝峰式命名法
- 將樣式對(duì)象直接寫到html中
render(){
return (
<div style={{marginLeft:'50px',marginTop:'50px'}}>
<button style={{margin:'auto 5px'}}>+</button>
<button style={{margin:'auto 5px'}}>-</button>
<span style={{margin:'auto 5px'}}>當(dāng)前點(diǎn)擊次數(shù)</span>
<span style={{margin:'auto 5px'}}>{this.state.count}</span>
</div>
)
}
可以看到更扁,style屬性中的內(nèi)容使用了兩層大括號(hào)盖腕,其中外層的大括號(hào)是React表達(dá)式,內(nèi)層的大括號(hào)是JavaScript對(duì)象
上述三種css的書寫方式的效果是一樣的浓镜,在后續(xù)的范例中溃列,為了讓代碼簡(jiǎn)單直觀,采用引入外部css文件的方式
按鈕事件
接下來為兩個(gè)按鈕增加點(diǎn)擊事件膛薛,react中的點(diǎn)擊事件為onClick
听隐,它與html中的onclick
有一些區(qū)別,在這里不進(jìn)行詳細(xì)描述哄啄。我們?yōu)榧犹?hào)按鈕增加事件處理函數(shù)increment
雅任,為減號(hào)增加事件處理函數(shù)decrement
风范。在increment
,讓state中的count的值加1,在decrement中,讓state中count的值減1
注意點(diǎn):
事件函數(shù)綁定this
修改state的方式
import React from 'react';
import '../style/App.css'
class App extends React.Component{
constructor(props){
super(props);
this.state = {
count:0
}
this.increment = this.increment.bind(this);
this.decrement = this.decrement.bind(this);
}
increment(){
this.setState({count:this.state.count+1})
}
decrement(){
this.setState({count:this.state.count-1})
}
render(){
return (
<div className="box">
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
<span>當(dāng)前點(diǎn)擊次數(shù)</span>
<span>{this.state.count}</span>
</div>
)
}
}
export default App;
- 修改state中的數(shù)據(jù)椿访,要調(diào)用setState函數(shù)來進(jìn)行設(shè)置
- 定義普通的的函數(shù)來處理事件乌企,需要在構(gòu)造函數(shù)中與this進(jìn)行綁定,否則在函數(shù)內(nèi)部成玫,
this
為undefined
此時(shí)我們?cè)陧撁纥c(diǎn)擊按鈕加酵,就能看到效果了
讓綁定this的方式完美一些
在上面的代碼中,我們可以看到哭当,事件處理函數(shù)要在構(gòu)造函數(shù)中調(diào)用bind函數(shù)來綁定this猪腕,在這里我們只有兩個(gè)函數(shù),在復(fù)雜引用中可能有更多的函數(shù)钦勘,要是每一個(gè)函數(shù)都要這么綁定一次陋葡,對(duì)于有強(qiáng)迫癥或者潔癖的開發(fā)人員來說是一件非常鬧心且痛苦的事情。因此我們要使用更加簡(jiǎn)潔的方式
請(qǐng)看代碼
import React from 'react';
import '../style/App.css'
class App extends React.Component{
constructor(props){
super(props);
this.state = {
count:0
}
}
increment = () => {
this.setState({count:this.state.count+1})
}
decrement = () => {
this.setState({count:this.state.count-1})
}
render(){
return (
<div className="box">
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
<span>當(dāng)前點(diǎn)擊次數(shù)</span>
<span>{this.state.count}</span>
</div>
)
}
}
export default App;
點(diǎn)擊按鈕效果完全一樣彻采,整個(gè)世界都干凈了腐缤!
從外部傳入數(shù)據(jù)
在前面我們說到,props是用來從外部傳遞數(shù)據(jù)的肛响,那么它是如何傳遞的呢岭粤?
在index.js中我們?yōu)锳pp標(biāo)簽添加屬性name
ReactDOM.render(<App name="當(dāng)前點(diǎn)擊次數(shù)"/>, document.getElementById('root'));
然后修改App.js中的render函數(shù)
render(){
return (
<div className="box">
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
<span>{this.props.name}</span>
<span>{this.state.count}</span>
</div>
)
}
運(yùn)行效果與之前是一樣的!
到這里呢特笋,這個(gè)簡(jiǎn)單而又覆蓋到react的大部分內(nèi)容的范例就說完了剃浇!上手試試,其實(shí)很簡(jiǎn)單的猎物!