1. 程式人生 > >初識React(3):元件

初識React(3):元件

建立元件

建立元件之前要注意以下幾點:
1. 元件建立的名稱首字母得大寫
2. 元件中返回的JSX只能是一個根節點,所有的內容得用一個元素都框起來

1.無狀態函式式元件

無狀態函式式元件可以理解成就是一個函式生成的,使得程式碼的可讀性更好,並且精簡、便利,減少了冗餘,無狀態元件有以下特點:
1. 元件無法被例項化,整體渲染提高
2. 元件不能訪問this物件,因為沒有例項化,所以無法訪問到this物件
3. 元件沒有生命週期
4. 無狀態元件只能訪問輸入的props,沒有state狀態

import React from 'react'
import { connect } from 'dva'
; function CreateComponent(props) { console.log(props); return ( <div> <span>{props.name}今年{props.age}歲</span> </div> ) } export default connect(state => ({ name:'小明', age:15 }))(CreateComponent);

2.React.Component類元件

每個元件類必須要實現一個render方法,這裡要特別注意,這個render方法必須要返回一個JSX元素即要用一個最外層的元素將所有內容都包裹起來,如果返回並列多個JSX元素是不合法,如下所示:

import React from 'react'

class CreateComponent extends React.Component {
     render() {
       return(
         <div>
           <h2>標題</h2>
            <ul>
              <li>首先</li>
              <li>其次</li>
              <li>最後</li>
            </ul>
         </div
> ) } } export default CreateComponent;

以上例項,就是把h2元素和ul用一個div都給包起來

1.元件的事件監聽

import React from 'react'

class CreateComponent extends React.Component {

   clickFunc = (e) => {
     console.log("監聽:",e.target.innerHTML);
   }

   clickValue = (value) => {
     console.log(value);
   }
    render() {
      return (
       <div>
         <a onClick={this.clickFunc}>監聽事件</a>
         <br/>
         <a onClick={this.clickValue.bind(this,123)}>this物件</a>
      </div>
      )
    }

}

export default CreateComponent;

以上就是事件監聽和傳參例項

2.元件的state和setState

通常在元件中,state是用來放這個元件內部引數的狀態的,而setState是用來改變state裡面的引數,例如:

import React from 'react'

class CreateComponent extends React.Component {
  state = {
    flag : true
  }
   clickValue = () => {
     this.setState({
       flag: !this.state.flag
     })
   }
    render() {
      return (
       <div>
         <span>flag的值為:{this.state.flag ? '真' : '假'}</span>
         <br/>
         <button onClick={this.clickValue}>改變flag值</button>
      </div>
      )
    }

}

export default CreateComponent;

3.元件的props

props是元件裡面的屬性,在元件內部是不能更改自己本身的props的,比如,建立一個元件,然後在另外一個元件裡面呼叫這個元件,如下:

import React from 'react';

function NewComponent(props) {
  return (
    <div>
       {props.content}
    </div>
  );
}


export default NewComponent;

建立一個元件NewComponent,然後呼叫,如下:

import React from 'react'
import NewComponent from './newComponent.js'

class CreateComponent extends React.Component {
    render() {
      return (
       <div>
         <NewComponent content={'我是內容'} />
      </div>
      )
    }

}

export default CreateComponent;

從這裡可以看出,props就是元件帶入的屬性值,props其實就是讓外部元件對自己進行配置,而state是元件控制自己的狀態

4.元件的生命週期

constructor元件初始化:

constructor初始化一些引數屬性等等

componentWillMount元件渲染之前:

componentWillMount這個函式在react16.3.0之後慢慢的被棄用了,使用componentDidMount替換

componentDidMount元件渲染之後:

componentDidMount在元件渲染之後實行,可以載入資料

render元件渲染:

render元件渲染顯示頁面

import React from 'react'

class CreateComponent extends React.Component {
  constructor () {
    super()
    console.log('construct:頁面初始化')
  }

  componentWillMount () {
    console.log('componentWillMount:頁面將要渲染')
  }

  componentDidMount () {
    console.log('componentDidMount:頁面渲染結束')
  }


    render() {
      console.log('render:頁面渲染');
      return (
       <div>
         頁面渲染
      </div>


      )
    }

}

export default CreateComponent;

輸出結果:

construct:頁面初始化
componentWillMount:頁面將要渲染
render:頁面渲染
componentDidMount:頁面渲染結束
componentWillUnmount元件刪除

componentWillUnmount函式是在元件要刪除之前執行的函式,如下程式碼:

import React from 'react';

class NewComponent extends React.Component {
  componentWillUnmount() {
    console.log('componentWillUnmount:將要從頁面中刪除');
  }

  render() {
    return (
      <div>
         {this.props.content}
      </div>
    );
  }

}

export default NewComponent;

建立一個元件NewComponent,然後在CreateComponent元件中引入這個元件,如下:

import React from 'react'
import NewComponent from "./newComponent.js";

class CreateComponent extends React.Component {
  constructor () {
    super()
    console.log('construct:頁面初始化');
    this.state = {
      content:'測試元件',
      isDelete:false
    }
  }

  componentWillMount () {
    console.log('componentWillMount:頁面將要渲染')
  }

  componentDidMount () {
    console.log('componentDidMount:頁面渲染結束')
  }

  deleteFunc = () => {
    this.setState({
      isDelete:true
    })
  }


    render() {
      console.log('render:頁面渲染');
      return (
       <div>
         頁面渲染
         <input type="button" value='刪除' onClick={this.deleteFunc}/>
         {!this.state.isDelete?(
          <NewComponent content={this.state.content}/>
         ):(null)}

      </div>


      )
    }

}

export default CreateComponent;

當點選刪除按鈕的時候,元件NewComponent會被刪除,在刪除之前會執行componentWillUnmount函式

輸出結果:

construct:頁面初始化
componentWillMount:頁面將要渲染
render:頁面渲染
componentDidMount:頁面渲染結束
componentWillUnmount:將要從頁面中刪除

以上幾個生命週期是我們會常用到的元件生命週期,元件的生命週期還有更新階段的生命週期,不過這些比較少用,這裡簡單介紹一下:

shouldComponentUpdate(nextProps, nextState)

通過這個方法控制組件是否重新渲染,如果返回false不會重新渲染,如下

import React from 'react'
import NewComponent from "./newComponent.js";

class CreateComponent extends React.Component {
  constructor () {
    super()
    console.log('construct:頁面初始化');
    this.state = {
      content:'測試元件',
      isDelete:false
    }
  }

  componentWillMount () {
    console.log('componentWillMount:頁面將要渲染')
  }

  componentDidMount () {
    console.log('componentDidMount:頁面渲染結束')
  }

  shouldComponentUpdate(nextProps, nextState){
    if(nextState.isDelete){
      return false;
    }

  }

  deleteFunc = () => {
    this.setState({
      isDelete:true
    })
  }


    render() {
      console.log('render:頁面渲染');
      return (
       <div>
         頁面渲染
         <input type="button" value='刪除' onClick={this.deleteFunc}/>
         {!this.state.isDelete?(
          <NewComponent content={this.state.content}/>
         ):(null)}

      </div>


      )
    }

}

export default CreateComponent;

此時點選刪除按鈕,頁面沒有進行渲染,那是因為在shouldComponentUpdate中設定了返回值為false,當返回值為false的時候,頁面無法重新渲染。這個函式第一個引數表示最新的props,第二個引數表示最新的state

componentWillReceiveProps(nextProps)

元件從父元件接收到新的 props 之前呼叫,函式的引數nextProps表示接收到的資料

在NewComponent元件中:

import React from 'react';

class NewComponent extends React.Component {
  componentWillUnmount() {
    console.log('componentWillUnmount:將要從頁面中刪除');
  }

  componentWillReceiveProps(nextProps){
    console.log(nextProps);
  }

  render() {
    return (
      <div>
         {this.props.content}
      </div>
    );
  }

}

export default NewComponent;

在元件CreateComponent中:

import React from 'react'
import NewComponent from "./newComponent.js";

class CreateComponent extends React.Component {
  constructor () {
    super()
    console.log('construct:頁面初始化');
    this.state = {
      content:'測試元件',
      isDelete:false
    }
  }

  componentWillMount () {
    console.log('componentWillMount:頁面將要渲染')
  }

  componentDidMount () {
    console.log('componentDidMount:頁面渲染結束')
  }

  changeFunc = () => {
    this.setState({
      content:'文字修改'
    })
  }


    render() {
      console.log('render:頁面渲染');
      return (
       <div>
         頁面渲染
         <input type="button" value='修改content' onClick={this.changeFunc}/>
         {!this.state.isDelete?(
          <NewComponent content={this.state.content}/>
         ):(null)}

      </div>


      )
    }

}

export default CreateComponent;

不過componentWillReceiveProps將在react16.3.0開始之後棄用

componentWillUpdate:

元件重新渲染之前呼叫這個方法,將在react16.3.0開始之後棄用

componentDidUpdate:

元件重新渲染並且把更改變更到真實的 DOM 以後呼叫

注意: componentWillUpdate、componentWillReceiveProps、componentWillMount這三個生命週期將在react16.3.0之後開始棄用,具體詳情可檢視官網:https://reactjs.org/docs/react-component.html#unsafe_componentwillmount