React學(xué)習(xí)總結(jié) 10.16

覺得比較重要的幾個(gè)點(diǎn)簡單做下筆記方便以后查

1.幾種創(chuàng)建組件的方式

  1. 組件生命周期相關(guān)的鉤子
  2. 父子組件通訊
  3. 高階組件的使用和定義 HOC

組件創(chuàng)建方式

  1. React.createClass // 已經(jīng)棄用(console直接把React對象打印出來可以加深對API的理解)
const Nav = React.createClass({
        render: function() {
            return ( 
                <ul>
                    <li>首頁</li>
                    <li>我的</li>
                </ul> 
            ) 
        } 
      });

// React 16.5對外暴露的方法
{
    Children: {map: ?, forEach: ?, count: ?, toArray: ?, only: ?}
    Component: ? Component(props, context, updater)
    Fragment: Symbol(react.fragment)
    PureComponent: ? PureComponent(props, context, updater)
    StrictMode: Symbol(react.strict_mode)
    cloneElement: ? cloneElementWithValidation(element, props, children)
    createContext: ? createContext(defaultValue, calculateChangedBits)
    createElement: ? createElementWithValidation(type, props, children)
    createFactory: ? createFactoryWithValidation(type)
    createRef: ? createRef()
    forwardRef: ? forwardRef(render)
    isValidElement: ? isValidElement(object)
    unstable_AsyncMode: Symbol(react.async_mode)
    unstable_Profiler: Symbol(react.profiler)
    version: "16.5.2"
}

  1. class Nav extends React.Component 通過繼承Component對象

class Nav extends Component{ };

class Nav extends React.Component{}

兩種方法一樣與模塊導(dǎo)入方式有關(guān)
import * as React from "React";  // 導(dǎo)入全部對象屬性和方法 只能使用第一種默勾,通過React.Component才能繼承

import React,{Component} from 'React' //可以使用以上任意方式繼承方法屬性

import { ObjOne, ObjTwo} from 'Obj' 可以引入多個(gè)方法

  1. function Nav (){} 通過函數(shù)定義無狀態(tài)組件

無狀態(tài)組件:適合用來聲明沒有組件生命周期方法并且沒有內(nèi)部狀態(tài)的組件位谋。

function Nav({ list }) { 
    return (
        <div> {map(list, (item) => <div>{item.name}</div>)} </div> 
    ); 

}

組件通訊

父組件(Teacher) ---> 子組件(Tim) props

class Tim extends Component {
  constructor(props) {
    super(props)
  }
  render() {
    return (
      <div>{this.props.notice}</div>
    )
  }
}
class Teacher extends Component {
  render() {
    return (
      <Tim notice="明天來上課"></Tim>
    )
  }
}

子組件(Tim) ---> 父組件(Teacher) 函數(shù)回調(diào)

場景: 操作DOM觸發(fā)

class Tim extends Component {
  constructor(props) {
    super(props)
  }
  render() {
    return (
      <div><input onChange={this.props.handleEmail}/></div>
    )
  }
}


class Teacher extends Component {
    handleEmail(event){
        console.log(event.target.value)
    }
  render() {
    return (
      <Tim handleEmail={this.handleEmail.bind(this)}></Tim>
    )
  }
}



場景: 在函數(shù)回調(diào)觸發(fā)


class Tim extends Component {
  constructor(props) {
    super(props)
  }
  handleClick(){
    this.props.handleEmail('他們已經(jīng)干我了!')
  }
  render() {
    return (
      <div>
        <div onClick={this.handleClick.bind(this)} > 快來干我褒颈!</div>
      </div>
    )
  }
}


class Teacher extends Component {
    handleEmail(event){
        console.log(event)
    }
  render() {
    return (
      <Tim handleEmail={this.handleEmail.bind(this)}></Tim>
    )
  }
}

子組件(Tim) ---> 父組件(Teacher) --->爺爺組件(Boss) 函數(shù)回調(diào)


class Tim extends Component {
  constructor(props) {
    super(props)
  }
  handleClick() {
    this.props.handleEmail('我爸是局長盾鳞!')
  }
  render() {
    return (
      <div>
        <div onClick={this.handleClick.bind(this)} > 快來干我意系!</div>
      </div>
    )
  }
}


class Teacher extends Component {
  handleEmail(event) {
    this.props.handleText(event)
    console.log("Teacher" + event)
  }
  render() {
    return (
      <Tim handleEmail={this.handleEmail.bind(this)}></Tim>
    )
  }
}

class Boss extends Component {
  handleText(event) {
    console.log("Boss" + event)
  }
  render() {
    return (
      <Teacher handleText={this.handleText.bind(this)}></Teacher>
    )
  }
}



兄弟組件通訊

Redux || 子組件(Tim) ----> (函數(shù)回調(diào)) 父組件(Teacher) ----> (props) 子組件(Jerry)

//子組件
class Tim extends Component {
  constructor(props) {
    super(props)
  }
  handleClick() {
    this.props.handleEmail('Jerry你是我最好的朋友父叙!')
  }
  render() {
    return (
      <div>
        <div onClick={this.handleClick.bind(this)} > 快來點(diǎn)我吧几莽!</div>
      </div>
    )
  }
}

//父組件
class Teacher extends Component {
  constructor() {
    super()
    this.state = {
      notice: ""
    }
  }
  handleEmail(val) {
    this.setState({
      notice: val
    })
    console.log(val)
  }
  render() {
    return (
      <div>
      <Tim handleEmail={this.handleEmail.bind(this)}></Tim> 
      <Jerry notice = {this.state.notice} > </Jerry>
      </div>
    )
  }
}

// 子組件
class Jerry extends Component {
  constructor(props) {
    super(props)
  }
  render() {
    return (
      <div>
        <div>{this.props.notice}</div>
      </div>
    )
  }
}

生命周期

初始化
  1. getDefaultProps()

設(shè)置默認(rèn)的props迅办,也可以用dufaultProps設(shè)置組件的默認(rèn)屬性.

  1. getInitialState()

在使用es6的class語法時(shí)是沒有這個(gè)鉤子函數(shù)的,可以直接在constructor中定義this.state章蚣。此時(shí)可以訪問this.props

  1. componentWillMount()

組件初始化時(shí)只調(diào)用站欺,以后組件更新不調(diào)用,整個(gè)生命周期只調(diào)用一次,此時(shí)可以修改state矾策。

  1. render()

react最重要的步驟磷账,創(chuàng)建虛擬dom,進(jìn)行diff算法贾虽,更新dom樹都在此進(jìn)行逃糟。此時(shí)就不能更改state了。

更新
  1. componentDidMount() * 常用

組件渲染之后調(diào)用蓬豁,只調(diào)用一次绰咽。此時(shí)可進(jìn)行請求數(shù)據(jù),返回?cái)?shù)據(jù)setState后組件會重新渲染 庆尘。此時(shí)this.getDOMNode()訪問真實(shí)的DOM元素剃诅。此時(shí)可以使用其它類庫操作DOM。

  1. componentWillReceiveProps(nextProps) * 常用

組件初始化時(shí)不調(diào)用驶忌,組件接受父組件改變后的props時(shí)調(diào)用矛辕。

  1. shouldComponentUpdate(nextProps, nextState)

唯一用于控制組件重新渲染的生命周期,react性能優(yōu)化非常重要的一環(huán)付魔。 組件接受新的state或者props時(shí)調(diào)用聊品,我們可以設(shè)置在此對比前后兩個(gè)props和state是否相同,如果相同則返回false阻止更新几苍,因?yàn)橄嗤膶傩誀顟B(tài)一定會生成相同的dom樹翻屈,這樣就不需要創(chuàng)造新的dom樹和舊的dom樹進(jìn)行diff算法對比,節(jié)省大量性能妻坝,尤其是在dom結(jié)構(gòu)復(fù)雜的時(shí)候

  1. componentWillUpdata(nextProps, nextState)

組件初始化時(shí)不調(diào)用伸眶,只有在組件將要更新時(shí)才調(diào)用, 此時(shí)可以修改state 刽宪?

  1. componentDidUpdate()

組件更新完畢后厘贼,組件初始化時(shí)不調(diào)用,組件更新完成后調(diào)用圣拄,此時(shí)可以獲取dom節(jié)點(diǎn)嘴秸。

卸載

  1. componentWillUnmount()

組件將要卸載時(shí)調(diào)用,一些事件監(jiān)聽和定時(shí)器需要在此時(shí)清除庇谆。

高階組件的使用和定義 (HOC)

概念

  • 高階組件通過包裹被傳入的React組件岳掐,經(jīng)過一系列處理,最終返回一個(gè)相對增強(qiáng)的 React 組件饭耳,供其他組件調(diào)用串述。一個(gè)高階組件只是一個(gè)包裝了另外一個(gè) React 組件的 React 組件。
  • 屬性代理(Props Proxy)( 高階組件操控傳遞給 WrappedComponent 的 props哥攘,)

使用

  1. 操作props (對需要傳入的props進(jìn)行攔截剖煌,添加材鹦、刪除逝淹、修改)
// 封裝

const HOC = (WrappedComponent) =>
  class WrapperComponent extends Component {
    render() {
      const msg = {
        ...this.props,
        Sex: 'Male'
      }
      return <WrappedComponent
                {...Sex}
            />;
    }
  }
// 使用
const Container = HOC(PageIndex);

<Container name="zhang"/>

// PageIndex print

{
    Sex: "Male"
    name: "Zhang"   
}


  1. 提升state

把被包裹組件(WrappedComponent)中的狀態(tài)提到包裹組件中 通過props把事件傳遞耕姊,然后通過回調(diào)把被包裹組件中state傳出來


class WrappedComponent extends Component {
  render() {
    return <div className="u-box" {...this.props.name} ></div>;
  }
}

const HOC = (WrappedComponent) =>
  class extends Component {
    constructor(props) {
      super(props);
      this.state = {
        name: '',
      };
      this.onNameChange = this.onNameChange.bind(this);
    }

    onNameChange(event) {
      console.log(event)
    }

    render() {
      const newProps = {
        name: {
          onClick: this.onNameChange,
        },
      }
      return <WrappedComponent {...newProps} />;
    }
  }


const Container = HOC(WrappedComponent)


  • 反向繼承(高階組件繼承(extends)WrappedComponent)

//對所有頁面增加Loading(反向繼承方式可以獲取父組件得props、state栅葡。實(shí)用性比較強(qiáng)茉兰,避免很多重復(fù)的勞動)
const HOC = (WrappedComponent) =>
  class HOC extends WrappedComponent {
    constructor(props) {
      super(props);
      console.log(props)
    }
    render() {
      if (!this.state.isLoading) {
        // 反向繼承
        return super.render()
      } else {
        return <Loading/>
      }
    }
  }

// 使用
const Container = HOC(PageIndex);

Vue中實(shí)現(xiàn)則需要通過插槽的方式把所有頁面插入到該組件中,通過子組件watch父組件傳入的值實(shí)現(xiàn)顯示隱藏欣簇。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末规脸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子熊咽,更是在濱河造成了極大的恐慌莫鸭,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件横殴,死亡現(xiàn)場離奇詭異被因,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)衫仑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門梨与,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人文狱,你說我怎么就攤上這事粥鞋。” “怎么了瞄崇?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵呻粹,是天一觀的道長。 經(jīng)常有香客問我苏研,道長等浊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任楣富,我火速辦了婚禮凿掂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘纹蝴。我一直安慰自己庄萎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布塘安。 她就那樣靜靜地躺著糠涛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兼犯。 梳的紋絲不亂的頭發(fā)上忍捡,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天集漾,我揣著相機(jī)與錄音,去河邊找鬼砸脊。 笑死具篇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的凌埂。 我是一名探鬼主播驱显,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瞳抓!你這毒婦竟也來了埃疫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤孩哑,失蹤者是張志新(化名)和其女友劉穎栓霜,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體横蜒,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胳蛮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了愁铺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹰霍。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖茵乱,靈堂內(nèi)的尸體忽然破棺而出茂洒,到底是詐尸還是另有隱情,我是刑警寧澤瓶竭,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布督勺,位于F島的核電站,受9級特大地震影響斤贰,放射性物質(zhì)發(fā)生泄漏智哀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一荧恍、第九天 我趴在偏房一處隱蔽的房頂上張望瓷叫。 院中可真熱鬧,春花似錦送巡、人聲如沸摹菠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽次氨。三九已至,卻和暖如春摘投,著一層夾襖步出監(jiān)牢的瞬間煮寡,已是汗流浹背虹蓄。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留幸撕,地道東北人薇组。 一個(gè)月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像杈帐,于是被迫代替她去往敵國和親体箕。 傳聞我的和親對象是個(gè)殘疾皇子专钉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容