React基礎學習

React是一個用于構(gòu)建用戶界面的JavaScript庫

一、基礎知識學習

1. JSX

const element = <h1>hello world<h1>

JSX是一個JavaScript的語法擴展遵循xml和html語法层宫。

可以在JSX中使用表達式:

const name = 'lucy';
const element = <h1>hello {name}</h1>;

ReactDOM.render(
  element,
  document.getElementById("root")
)

JSX也是一個表達式
可以在if語句和for循環(huán)語句的代碼塊中使用JSX,將JSX賦值給變量洞翩,把JSX當做參數(shù)傳入馁启,以及從函數(shù)中返回JSX

var name = "lucy"
function greeting(name){
  if(name){
    return <h1>Hello, {name}</h1>
  }
  return <h1>Hello Stranger</h1>
}

JSX特定屬性

const element = <div name="lucy"></div>
const element = <img src={user.avatar}></img>

注意:JSX語法上更接近JS蒋院,所以React DOM使用小駝峰(cameCase)命名來定義屬性的名稱厢绝,而不使用HTML屬性名稱的命名約定买决。
例如沛婴,JSX中class變成了ClassName,onclick變成了onClick.

2. 組件

類似于JS函數(shù),接受任意入?yún)ⅲ╬rops),并返回用于描述頁面展示內(nèi)容的React元素督赤。

函數(shù)組件

function Welcome(props){
  return <h1>Hello {props.name}</h1>
}

class組件

class Welecome extends React.Component{
  render(){
    return <h1>Hello,{this.props.name}</h1>
  }
}

這兩個組件在React里是等效的嘁灯。

注意:組件名稱必須大寫字母開頭(React會將小寫字母開頭組件視為原生DOM標簽)

3. Props

純函數(shù):函數(shù)不會更改入?yún)ⅲ叶啻握{(diào)用下相同的入?yún)⑹冀K返回相同的結(jié)果躲舌。

function sum(a,b){
  return a+b
}

組件無論如何都不能修改自身props丑婿,所有的組件都必須像純函數(shù)一樣保護它們的props不被修改。
定義與使用:

function Welcome (props){
  return <h1>{props.name}</h1>
}

ReactDOM.render(
  <Welcome name="jack"/>,
  document.getElementById("root")
)

4. State

State與props類似,但是state是私有的羹奉,并且完全受控于當前組件秒旋,可以將當前組件state當做子組件的props傳遞。
定義與使用:

class Welcome extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      name:"lucy"
    }
  }
  render(){
    return(
      <div>
        <h1>welcome!!!</h1>
        <h1>{this.state.name}</h1>
      </div>
    )
  }
}

ReactDOM.render(
  <Welcome/>,
  document.getElementById("root")
)

5. setState

React規(guī)定不要直接修改State
因此需要使用setState()方法實現(xiàn)修改state

例如尘奏,此代碼不會重新渲染組件

//假如組建中state為 this.state = {name : "jack"}
this.state.name = "lucy"

而使用setState就可以

this.setState({
  name:"lisa"
})

構(gòu)造函數(shù)是唯一可以給this.state賦值的地方滩褥。

State的更新可能是是異步的。
因為this.props和this.state可能會異步更新炫加,所以不要依賴他們的值瑰煎。

//wrong
this.setState({
  name:this.state.firstName + this.props.lastName,
})

解決:讓setState()接收一個函數(shù)而不是一個對象,這個函數(shù)用上一個state作為第一個參數(shù)俗孝,將此次更新被應用時的props作為第二個參數(shù):

//correct
this.setState((state,props)=>{
  name:state.firstName + props.lastName 
});

setState方式是異步的:

//...假設組件的state = {name:"lisa"},組件上有個按鈕點擊執(zhí)行handleClick事件
handleClick(){
  this.setState({
    name:"lucy"
  },()=>{
    console.log("setState()執(zhí)行完畢")
  })
  console.log('setState()執(zhí)行之前')
}

setState()方法接收第二個參數(shù)酒甸,類似于一個回調(diào)函數(shù),當數(shù)據(jù)更新之后才會執(zhí)行回調(diào)里面的方法赋铝,上述代碼輸出順序為“setState()執(zhí)行之前”=>“setState()執(zhí)行完畢”插勤。

關(guān)于setState可以參考這篇文章:你真的理解setState嗎?

6. 生命周期

組件生命周期三個階段

  • Mounting(加載階段)
  • Updating(更新階段)
  • Unmounting(卸載階段)


    react生命周期

Mounting階段執(zhí)行鉤子函數(shù):

  • constructor
  • getDefaultProps
  • getInitialState
  • componentWillMount
  • render
  • componentDidMount

Updating階段執(zhí)行鉤子函數(shù):
當props發(fā)生改變

  • compoentWillReceProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

當state發(fā)生改變

  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

Unmounting階段執(zhí)行鉤子函數(shù):

  • componentWillMount

7. 事件處理

  • React事件的命名采用小駝峰式(camelCase)革骨,而不是純小寫农尖。
  • 使用JSX語法時需要傳入一個函數(shù)作為事件處理函數(shù),而不是一個字符串良哲。

事件處理函數(shù)中的this:

class Toggle extends React.Component {
  constructor(props){
    super(props)
    this.state = {isToggle:true};
  }
  handleClick(){
    this.setState((state)=>({
       isToggle:!state.isToggle
    }));
  }
  render(){
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggle ? "ON" : "OFF"}
      </button>
    )
  }
  ReactDOM.render(
    <Toggle />,
    document.getElementById("root")
  )
}

此時handleClick中的this指向為undefined盛卡,因為this.handleClick傳給了button組件后是丟失了this的!如下:

var obj = {
  f : function(){
    console.log(this)
  }
}

function foo(f){
  f()
}
foo(obj.f)

個人覺得這個例子很形象筑凫,foo運行時接收到的參數(shù) f 時滑沧,foo是并不知道 f 是obj的屬性,也就是常說的丟失了上下文巍实。

關(guān)于React中this指向問題可以參考知乎文章https://www.zhihu.com/question/68092028?sort=created

this指向更正比較主流的有三種滓技,第一種是在調(diào)用時綁定:

render(){
  return (
      <button onClick={this.handleClick.bind(this)}>
        {this.state.isToggle ? "ON" : "OFF"}
      </button>
  )
}

第二種是在constructor中綁定:

constructor(){
  this.handleClick = this.handleClick.bind(this);
}
render(){
     <button onClick={this.handleClick}>
        {this.state.isToggle ? "ON" : "OFF"}
      </button>
}

第三種是使用public class fields語法:

handleClick = ()=>{
  console.log(this)
}
render(){
  return ( 
    <button onClick = {this.handleClick}>
      Click me
    </button>
  )
}

還有一種是在調(diào)用的時候直接用一個箭頭函數(shù)包起來:

render(){
  return ( 
    <button onClick = {()=>{this.handleClick()}}>
      Click me
    </button>
  )
}

響事件處理程序中傳遞參數(shù):

handleClick(id,e){
   e.preventDefault();
}

<button onClick = {(e)=>{this.handleClick(id,e)}}>Delete</button>

<button onClick={this.deleteRow.bind(this, id)}>Delete</button>

這兩種情況下,React的事件對象e會被作為第二個參數(shù)傳遞棚潦,如果通過箭頭函數(shù)的方式令漂,事件對象必須顯式的進行傳遞,而通過bind的方式瓦盛,事件對象以及更多的參數(shù)將會被隱式的進行傳遞洗显。

8. 組件通信

父子通信:通過props數(shù)據(jù)由父組件流向子組件

// Father.js
import React , {Component} from 'react';
import Child from './Child';
export default class Father extends Component {
    constructor(){
        super()
        this.state = {
            name:"father",
            age:20
        }
    }
    render(){
        return(
        <div>
            {this.state.name}
            <div><Child faname={this.state.name}/></div>
        </div>
        )
    }
}
//Child.js
import React ,{ Component }  from 'react'
export default class Child extends Component{
    constructor(){
        super()
        this.state = {
            name:"Child",
            age:10
        }
    }
    render(){
        return (
        <div>{this.state.name}</div>
        )
    }
    componentWillMount(){
        this.setState({
            name:this.props.faname
        })
    }
}

父組件中的state通過給子組件傳遞屬性的方式傳遞給子組件,子組件可以通過this.props.屬性名獲取到原环。

子父通信:通過方法通信(可以理解為回調(diào)函數(shù)通信)挠唆,在子組件中觸發(fā)一個通過props接收的從父組件傳遞過來的事件,并把子組件的state通過參數(shù)傳遞給事件嘱吗,這樣在父組件的方法中就能獲通過參數(shù)獲取子組件中的state

//Father.js
import React , {Component} from 'react';
import Child from './Child';
export default class Father extends Component {
    constructor(){
        super()
        this.state = {
            name:"father",
            age:20
        }
    }
    render(){
        return(
        <div>
            {this.state.name}
            <div><Child toChildEvent = {this.getChildState.bind(this)}/></div>
        </div>
        )
    }
    getChildState(childName){
        this.setState({
            name:childName
        })
    }
}

//Child.js
import React ,{ Component }  from 'react'
export default class Child extends Component{
    constructor(){
        super()
        this.state = {
            name:"Child",
            age:10
        }
    }

    render(){
        return (
        <div>{this.state.name}</div>
        )
    }
    componentWillMount(){
        this.props.toChildEvent(this.state.name);
    }
}

首先在父組件中定義一個方法玄组,叫做getChildState滔驾,然后通過屬性綁定給<Child/>組件,屬性名為toChildEvent(自定義)俄讹,之后在子組件中通過props接收到該toChildEvent屬性哆致,也就是getChildState方法,然后在componentWillMount生命周期鉤子函數(shù)中執(zhí)行患膛,并傳入?yún)?shù)摊阀,然后就在父組件中getChildState方法可以通過參數(shù)獲得子組件中state

兄弟通信:采用狀態(tài)提升方案踪蹬,將兄弟間需要共享的數(shù)據(jù)胞此,通過子父方法通信傳遞給最近共同父組件,之后通過父組件再通過props將數(shù)據(jù)流向各子組件

可以參考官網(wǎng)狀態(tài)提升

待續(xù)跃捣。漱牵。。疚漆。酣胀。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末娶聘,一起剝皮案震驚了整個濱河市闻镶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌丸升,老刑警劉巖儒溉,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異发钝,居然都是意外死亡,警方通過查閱死者的電腦和手機波闹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門酝豪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人精堕,你說我怎么就攤上這事孵淘。” “怎么了歹篓?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵瘫证,是天一觀的道長。 經(jīng)常有香客問我庄撮,道長背捌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任洞斯,我火速辦了婚禮毡庆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己么抗,他們只是感情好毅否,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蝇刀,像睡著了一般螟加。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吞琐,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天捆探,我揣著相機與錄音,去河邊找鬼顽分。 笑死徐许,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的卒蘸。 我是一名探鬼主播雌隅,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼缸沃!你這毒婦竟也來了恰起?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤趾牧,失蹤者是張志新(化名)和其女友劉穎检盼,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翘单,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡吨枉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了哄芜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片貌亭。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖认臊,靈堂內(nèi)的尸體忽然破棺而出圃庭,到底是詐尸還是另有隱情,我是刑警寧澤失晴,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布剧腻,位于F島的核電站,受9級特大地震影響涂屁,放射性物質(zhì)發(fā)生泄漏书在。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一胯陋、第九天 我趴在偏房一處隱蔽的房頂上張望蕊温。 院中可真熱鬧袱箱,春花似錦、人聲如沸义矛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凉翻。三九已至了讨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間制轰,已是汗流浹背前计。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留垃杖,地道東北人男杈。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像调俘,于是被迫代替她去往敵國和親伶棒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355