react學習-5.React組件

前面的示例都是渲染的元素,主要是用來闡述ReactDOM.render()工作原理。通常在React項目中是不這樣做的。我們常常會它封裝到一個React組件中,然后再通過ReactDOM.render()把這個組件渲染出來。

  • 在React中元素是構成React應用的最小單位。

1.什么是組件

  • React是專注于View層的,組件也是React核心理念之一,一個完整的應用將由一個個獨立的組件拼裝而成。React組件可以看成構造出一個虛擬DOM結構的對象

2.React創(chuàng)建組件的方式

在React中創(chuàng)建組件有三種方式:

  1. 有狀態(tài)組件(ES6寫法):React.Component
  2. 有狀態(tài)組件(ES5寫法):React.createClass(注:此方法舊版本react可用,現(xiàn)已不可用
  3. 無狀態(tài)組件的函數(shù)寫法(函數(shù)組件)。

3.有狀態(tài)?無狀態(tài)?

  • 無狀態(tài)組件,它是一種只負責展示的純組件。這種組件只負責根據(jù)傳入的props來展示,不涉及到要state狀態(tài)、生命周期等操作。
  • 有狀態(tài)組件,需要涉及state、生命周期等操作。
  • React鼓勵在大型項目中盡可能以無狀態(tài)組件的寫法 來分割原本龐大的組件。

4.React.createClass

注:React.createClass方法現(xiàn)已經不可用,本文章總結只是為了和es6寫法作對比,從而更好的理解。

React.createClass是React剛開始創(chuàng)建組件的方式。這是ES5的原生的JavaScript封裝的函數(shù)來實現(xiàn)的React組件。

動手敲個小例子

我們用一個小例子來了解一下組件的創(chuàng)建的機制。該例子包含一個文本框和一個按鈕,單擊按鈕可以改變文本框的編輯狀態(tài):禁止編輯或允許編輯。并且顯示自定義屬性文本。

image
   var  SwitchInput = React.createClass({
        getDefaultProps : function () {
            return {myattr: "我是默認的屬性"}
        }
        getInitialState:function(){
            return {enable:false}
        },
        handleClick:function(event){
            this.setState({enable:!this.state.enable})
        },
        render:function(){
            return (
                <p>
                    <input type="text" disabled={this.state.enable} />
                    <button onClick={this.handleClick}>改變textbox狀態(tài)</button>
                </p>
            )
        }
    });

    ReactDOM.render(<SwitchInput myattr="我是傳過來的屬性"/>, document.getElementById('root'));

state:

  • 組件總是需要和用戶互動的。React的一大創(chuàng)新,就是將界面組件看成一個狀態(tài)機,用戶界面擁有不同狀態(tài)并根據(jù)狀態(tài)進行渲染輸出,用戶界面和數(shù)據(jù)始終保持一致。開發(fā)者的主要工作就是定義state,并根據(jù)不同的state渲染對應的用戶界面。

setState()

  • React自帶方法。通知React組件數(shù)據(jù)發(fā)生變化的方法是調用成員函數(shù)setState(data,callback)。這個函數(shù)會合并data到this.state,并重新渲染組件。

getInitialState

  • 存放state的容器。

props即屬性(Property), 在代碼中寫作 props , 即可用 props 指代 properties .

  • 組件的屬性

getDefaultProps

  • 存放props的容器

render

  • 用于將模板轉為HTML語言,并插入指定的DOM節(jié)點。

props和state的區(qū)別

  • props是只讀的,不能在組件中修改,只能通過組件傳遞;state只能在所在組件內部更改,或在外部調用setState函數(shù)對狀態(tài)進行間接修改。

  • 在設計組件時,就要想好組件哪些使用state,哪些使用props集合,哪些使用state集合。通常固定的組件內只讀的、由父組件傳遞進來的屬性適合放在props集合中。

5.React.Component

ES6中類的出現(xiàn)改變了我們定義組件的方式,如今,React.createClass已經不可使用,新版本的react創(chuàng)建有狀態(tài)組件都是使用React.component來創(chuàng)建。

我們將上面例子使用es6的方法改寫下。

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';

class SwitchInput extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      enable: true
    }
   
    this.handleClick = this.handleClick.bind(this) //綁定this
  }

  handleClick(event) {
    this.setState({
      enable: !this.state.enable
    })
  }
  render() {
      return (
       <p>
         <input type="text" disabled={this.state.enable}/>
         <button onClick={this.handleClick}>
              改變輸入框編輯狀態(tài)
         </button>
         自定義屬性:{this.props.myattr}
       </p>
      )
  }
}
SwitchInput.defaultProps={
  myattr: "我是默認的屬性" 
} 
SwitchInput.propTypes = {
  myattr: PropTypes.string
};



ReactDOM.render(<SwitchInput myattr="我是傳過來的屬性"/>, document.getElementById('root'));
  • 默認屬性放到defaultProps中
  • state值放到constructor構造函數(shù)中。
  • prop-types庫是react自帶的屬性類型檢測庫。這里設置myattr為字符串類型,若傳入其他類型,會在控制臺報錯。具體可查看官網。http://www.css88.com/react/docs/typechecking-with-proptypes.html

不清楚constructor以及super等寫法可以看我之前的文章。ES6學習-類(Class)的聲明1

React.createClass與React.Component區(qū)別

根據(jù)上面展示代碼中二者定義組件的語法格式不同之外,二者還有很多重要的區(qū)別,下面就描述一下二者的主要區(qū)別。

  • React.Component可以有選擇性的綁定需要的函數(shù),React.createClass會自動綁定函數(shù),這樣會導致不必要的性能開銷。
  • 函數(shù)this自綁定

React.createClass創(chuàng)建的組件,其每一個成員函數(shù)的this都有React自動綁定,任何時候使用,直接使用this.method即可,函數(shù)中的this指向類的實例。

const Contacts = React.createClass({  
  handleClick() {
    console.log(this); // React 實例
  },
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
});

React.Component創(chuàng)建的組件,其成員函數(shù)不會自動綁定this,需要開發(fā)者手動綁定,否則this不能獲取當前組件實例對象。

class Contacts extends React.Component {  
  constructor(props) {
    super(props);
  }
  handleClick() {
    console.log(this); // null
  }
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }

具體綁定方法有三種:

  1. 在構造函數(shù)中綁定this.

     constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this); //構造函數(shù)中綁定
     }
    
  2. 直接在結構中綁定

     <div onClick={this.handleClick.bind(this)}></div> //使用bind來綁定
    
  3. 使用箭頭函數(shù)綁定

     <div onClick={()=>this.handleClick()}></div> //使用arrow function來綁定
    

綁定成功后,這樣在自定義函數(shù)中間就可以使用this了,若不使用this可以不綁定。

6.無狀態(tài)組件

無狀態(tài)組件其實是通過函數(shù)形式或者ES6 arrow function的形式創(chuàng)建的,它是為了創(chuàng)建純展示組件。這種組件只負責根據(jù)傳入的props來展示,不涉及到state狀態(tài)的操作。

function HelloComponent(props) { 
  return <div>Hello {props.name}</div>
} 
 ReactDOM.render(<HelloComponent name="react" />, document.getElementById('root'))  //Hello react

react鼓勵盡量使用無狀態(tài)組件。其又以下幾個顯著特點:

  • 無狀態(tài)組件的創(chuàng)建形式使代碼的可讀性更好,并且減少了大量冗余的代碼,精簡至只有一個render方法,大大的增強了編寫一個組件的便利。
  • 組件不會被實例化,無實例化過程也就不需要分配多余的內存,從而整體渲染性能得到提升
  • 組件不能訪問this對象。(無狀態(tài)組件由于沒有實例化過程,所以無法訪問組件this中的對象,例如:this.ref、this.state等均不能訪問。若想訪問就不能使用這種形式來創(chuàng)建組件)
  • 組件無法訪問生命周期的方法(因為無狀態(tài)組件是不需要組件生命周期管理和狀態(tài)管理)
  • 無狀態(tài)組件只能訪問輸入的props,不涉及state等操作。

下一篇——react學習-6.React組件的生命周期

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容