開發(fā)react須知

react官網(wǎng)教程基礎(chǔ)解析

1刁卜、使用redux和沒有redux锈锤,react寫法有什么不同嗎摔寨?

答:組件寫法一樣,但是state不一定交給組件內(nèi)部管理竭望,可能放到store上統(tǒng)一管理邪码。

2、認(rèn)識react市框,一個(gè)hello world霞扬!

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);

3、如何使用react枫振?

答:推薦你使用ES6語法來寫react喻圃,首先你需要Babel編譯你的ES6代碼,其次粪滤,你才可以使用比如 => (箭頭函數(shù))斧拍,class(類),模板文字杖小,let和const語句等ES6語法肆汹。

4、JSX介紹

答:JSX是一種表達(dá)式予权,它有一個(gè)根標(biāo)簽昂勉,在內(nèi)部可以嵌入表達(dá)式,使用{}(大括號)包裹起來扫腺。它看起來就是html的一部分岗照,或者叫一個(gè)html模塊。

class T extends React.Component {
    render() {
        return <div className="left-enter" style={}>{value}</div>
    }
}

從上面的代碼例子你可以看到幾個(gè)和html不同的地方笆环,class =》className攒至,style是一個(gè)object,你還可以在dom元素中使用{}插入數(shù)據(jù)躁劣。

使用JSX還可以防止XSS(跨站腳本攻擊)迫吐,因?yàn)镴SX只是表達(dá)式,它需要先轉(zhuǎn)換成字符串账忘,然后才能渲染到真實(shí)DOM上面志膀,但對于真正的黑客來說熙宇,這種做法也不是安全的。

4梧却、元素和組件的概念

react組件:

class T extends React.Component {
    render() {
        return <div className="left-enter" style={}>{value}</div>
    }
}

react元素:

<div className="left-enter" style={}>{value}</div>

5奇颠、組件的使用

函數(shù)組件:函數(shù)組件沒有狀態(tài)和生命周期,但是你可以返回一個(gè)react元素放航。

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

class組件:非常強(qiáng)大烈拒,有自己的state和生命周期。和函數(shù)組件一樣广鳍,class組件也需要返回一個(gè)react元素荆几。

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

在一個(gè)龐大復(fù)雜的網(wǎng)站應(yīng)用中,要如何拆分組件呢赊时?官網(wǎng)上說組件拆分的越細(xì)吨铸,復(fù)用性就越強(qiáng),從實(shí)際開發(fā)中來看祖秒,這個(gè)說法沒有錯(cuò)诞吱,但是
會(huì)帶來一個(gè)比較嚴(yán)重的問題,就是組件太多竭缝,管理起來不方便房维。有人使用第三方react組件的時(shí)候,只有那些文檔非常強(qiáng)大的開源組件
才能給你的開發(fā)提高效率抬纸。如果你自己的組件也想拆分到細(xì)致咙俩,那么寫好文檔是最重要的一步。

react還提到了一點(diǎn)湿故,傳遞給組件的數(shù)據(jù)是"只讀"的阿趁,要保證組件中的數(shù)據(jù)是"純數(shù)據(jù)",輸入即輸出坛猪。那么脖阵,如果你需要在組件中修改props.data
該怎么做呢?

render() {
    const { data } = this.props
    //定義一個(gè)新的變量來保存修改后的值墅茉。
    let _data = data + 1;
}

6独撇、組件的狀態(tài)和生命周期

前面我們提到組件分為函數(shù)組件和類組件,函數(shù)組件是無狀態(tài)躁锁,類組件有狀態(tài)和生命周期。

什么是狀態(tài)卵史?

答:通俗理解战转,就是組件不同時(shí)候的不同表現(xiàn),比如以躯,一個(gè)按鈕組件槐秧,可能有激活狀態(tài)啄踊,不可點(diǎn)擊狀態(tài),顯示狀態(tài)刁标,隱藏狀態(tài)等颠通,在react用state來保存這些狀態(tài)。
而state本身不僅僅表示組件狀態(tài)膀懈,還可以保存組件的數(shù)據(jù)顿锰。

class Button extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
        isShow: true,
        text: props.text,
        disabled: true
    };
  }

  render() {
      const { isShow, text, disabled} = this.state
      return <button disabled={disabled} style={{display: isShow ? "block" : "none"}}>{text}</button>
  }
}

如果要修改state,請使用启搂,注意硼控,你不能在render函數(shù)里面直接修改state,而是要通過事件去觸發(fā)state更新胳赌。

this.setState({
    isShow: false,
    disabled: false
})

由于setState有批處理功能牢撼,所以該方法可能不一定同步更新,如果你需要依賴上一次的狀態(tài)和本次狀態(tài)的計(jì)算疑苫,那么需要寫成下面這種形式熏版。

this.setState((prevState, props) => {    
      text: prevState.text++
    });

demo網(wǎng)址:http://codepen.io/hyy1115/pen/GmdOKJ?editors=0011

有時(shí)候,子組件不需要關(guān)注自身的狀態(tài)捍掺,而是通過父組件的狀態(tài)來改變撼短,這時(shí)候的子組件可以寫成函數(shù)形式,通過props傳遞父組件給的狀態(tài)乡小。

react生命周期
生命周期表示組件的一生阔加,從出生到輝煌到死亡,中間最主要也是最常用的3個(gè)狀態(tài)是:

componentWillMount:出生了满钟,把組件的狀態(tài)和屬性都設(shè)置好胜榔。

componentDidMount:渲染出來了,我不再是JSX湃番,而是真實(shí)DOM了夭织。

componentWillUnmount:要死了,死之前把遺產(chǎn)處理好吠撮。

class Button extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
        isShow: true,
        text: props.text,
        disabled: true
    };
  }
  
  componentWillMount() {
      //出生了尊惰,可以給我數(shù)據(jù)和設(shè)置我的狀態(tài)
  }
  componentDidMount() {
      //活著多好
  }
  componentWillUnmount() {
      //要死了,把我的一生痕跡都清除
  }

  render() {
      const { isShow, text, disabled} = this.state
      return <button disabled={disabled} style={{display: isShow ? "block" : "none"}}>{text}</button>
  }
}

還有其他幾個(gè)生命周期泥兰,并不是非常常用弄屡,需要用到的時(shí)候去看下別人的博客。

7鞋诗、事件處理

 <button onClick={(e) => this.handleClick(e)}>
 按鈕
</button>

<input type="text" onChange={(e) => this.handleClick(e)} />

8膀捷、條件渲染

前面button的例子我們已經(jīng)使用到了條件渲染,條件渲染通過state來判斷削彬,常用的是控制style全庸、className秀仲、DOM屬性,JSX壶笼。

舉幾個(gè)常用的例子神僵。

render() {
    return (
        <div>
        {
            this.state.isShow && <button>按鈕</button>    
        }
        </div>
    )
}
render() {
    return (
        <div>
        {
            this.state.isShow ? <button>按鈕</button> : <span>文本</span>
        }
        </div>
    )
}
render() {
    return <button disabled={this.state.disabled}>按鈕</button>
}

9、列表渲染

2個(gè)注意點(diǎn):

數(shù)組要判斷是否為空覆劈;

必須給一個(gè)key保礼。

render() {
    const { arr } = this.state
    return arr.length > 0 && arr.map((value, key) => <li key={key}>{value}</li> )
}

10、表單

我曾經(jīng)經(jīng)歷過的一次阿里的面試墩崩,就考到了react表單的知識點(diǎn)氓英。

受控組件:由react控制輸入的表單組件。

在下面的例子中鹦筹,input的value值由state來決定铝阐,用戶輸入觸發(fā)onChange事件,然后更新state铐拐,達(dá)到修改value的目的徘键。

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  render() {
    return (
          <input type="text" value={this.state.value} onChange={this.handleChange} />
    );
  }
}

或許你沒看出來和正宗input元素的區(qū)別,看一個(gè)真實(shí)DOM元素的例子,value由inupt自身維護(hù)遍蟋,我們沒有給value綁定值吹害。

<input type="text">

textarea和input是一樣的用法。

select有些許不同虚青,將value綁定到select上它呀,而不是option。

<select value={this.state.value} onChange={this.handleChange}>
    <option value="1">1</option>
    <option value="2">2</option>
</select>

還有一種是多個(gè)輸入框的情況棒厘,比如登錄纵穿,有賬號、密碼等奢人,這時(shí)候操作這些不同的input可以通過ref或者name谓媒,class,id等方法去setState何乎,看
官方demo句惯。

class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

    this.setState({
      [name]: value
    });
  }

  render() {
    return (
      <form>
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
      </form>
    );
  }
}

不受控組件:很簡單,就是DOM自己維護(hù)狀態(tài)的組件支救,不受react控制抢野。你可以給它設(shè)置defaultValue,但是不能去setState各墨。

<input type="text" ref={(input) => this.input = input} defaultValue="默認(rèn)值"/>

相信有人會(huì)試過設(shè)置defaultValue之后執(zhí)行了setState去修改value指孤,這樣做控制臺(tái)會(huì)發(fā)出警告。

總結(jié):受控組件是指受react控制的組件欲主,表單組件中的value和state同步邓厕,不受控組件是指不受react控制的組件,表單組件中的
value不通過state同步扁瓢,只能操作DOM去讀取value详恼。

11、狀態(tài)提升

你一定聽說過變量提升引几,函數(shù)提升昧互,那么狀態(tài)提升是什么呢?

首先你得了解雙向綁定和單向數(shù)據(jù)流伟桅,雙向綁定中敞掘,數(shù)據(jù)可以在不同的組件之間實(shí)現(xiàn)共享,這樣做的確有很大的好處楣铁,但是在react中玖雁,
不推薦使用雙向綁定,而是使用狀態(tài)提升的方式盖腕。

記得和阿里的一個(gè)面試官聊的時(shí)候赫冬,他要求我用react實(shí)現(xiàn)雙向綁定,而我認(rèn)為react應(yīng)該采用狀態(tài)提升來實(shí)現(xiàn)溃列。最后沒說服他劲厌,或許讓Dan來
和他聊聊才有用,哈哈听隐。

狀態(tài)提升:state推崇單向數(shù)據(jù)流补鼻,數(shù)據(jù)從父組件通過props流向子組件,如果你在子組件中雅任,需要修改state來和其他子組件共享數(shù)據(jù)更新风范,
你需要使用回調(diào)函數(shù)給使數(shù)據(jù)更新給父組件,然后從父組件流向其他的子組件椿访,這樣做是保證數(shù)據(jù)有單一的來源乌企。

如果實(shí)子組件和子組件之間任意共享數(shù)據(jù),那么成玫,后期維護(hù)會(huì)比較痛苦加酵,特別是找bug的時(shí)候。

看一個(gè)狀態(tài)提升的例子吧哭当。


class Child extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.props.upDateValue(e.target.value);
  }

  render() {
    const {name, value} = this.props;
    return (
      <div>
        <p>{name}:</p>
        <input value={value}
               onChange={this.handleChange} 
          />
      </div>
    );
  }
}

class Demo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: '', name: ''};
    
    this.upDateValue = this.upDateValue.bind(this);
  }

  upDateValue(value) {
    this.setState({value: value})
  }
  
  render() {
    const {value} = this.state;

    return (
      <div>
        <Child name="組件1" value={value} upDateValue={this.upDateValue} />
        <Child name="組件2" value={value} upDateValue={this.upDateValue} />
      </div>
    );
  }
}

ReactDOM.render(
  <Demo />,
  document.getElementById('root')
);

demo網(wǎng)址:http://codepen.io/hyy1115/pen/xdjoZQ?editors=0011

12猪腕、選擇組合還是繼承?

用過原生js或者jQuery的同學(xué)可能對基礎(chǔ)非常熟悉钦勘,繼承可以實(shí)現(xiàn)擴(kuò)展很多功能陋葡。

在react組件開發(fā)中,我們的每個(gè)react組件都是繼承于React.Component彻采。

class MyComponent extends React.Component {
    
}

我們不推薦你繼承MyComponent腐缤。

//不推薦
class NextComponent extends MyComponent {
    
}

你應(yīng)該充分利用react組件的強(qiáng)大性能捌归,開發(fā)各種你需要的組件繼承至React.Component。組件之間的嵌套非常強(qiáng)大岭粤,你可以嵌套函數(shù)組件惜索,嵌套類組件。

詳情前往:https://facebook.github.io/react/docs/composition-vs-inheritance.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末剃浇,一起剝皮案震驚了整個(gè)濱河市巾兆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌虎囚,老刑警劉巖角塑,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異淘讥,居然都是意外死亡圃伶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門适揉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來留攒,“玉大人,你說我怎么就攤上這事嫉嘀×堆” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵剪侮,是天一觀的道長拭宁。 經(jīng)常有香客問我,道長瓣俯,這世上最難降的妖魔是什么杰标? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮彩匕,結(jié)果婚禮上腔剂,老公的妹妹穿的比我還像新娘。我一直安慰自己驼仪,他們只是感情好掸犬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著绪爸,像睡著了一般湾碎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奠货,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天介褥,我揣著相機(jī)與錄音,去河邊找鬼。 笑死柔滔,一個(gè)胖子當(dāng)著我的面吹牛溢陪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播睛廊,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嬉愧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了喉前?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤王财,失蹤者是張志新(化名)和其女友劉穎卵迂,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绒净,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡见咒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挂疆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片改览。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖缤言,靈堂內(nèi)的尸體忽然破棺而出宝当,到底是詐尸還是另有隱情,我是刑警寧澤超营,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布渔期,位于F島的核電站婶溯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏订晌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一蚌吸、第九天 我趴在偏房一處隱蔽的房頂上張望锈拨。 院中可真熱鬧,春花似錦羹唠、人聲如沸奕枢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽验辞。三九已至,卻和暖如春喊衫,著一層夾襖步出監(jiān)牢的瞬間跌造,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留壳贪,地道東北人陵珍。 一個(gè)月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像违施,于是被迫代替她去往敵國和親互纯。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354