1. 程式人生 > >元件高階知識(受控元件,無狀態元件,高階元件,純元件)

元件高階知識(受控元件,無狀態元件,高階元件,純元件)

元件高階知識

受控元件(controlled components)

在原生的表單中,input的值是這麼設定的。

<input value="mapbar_front" />

並且在這種情況下,我們能夠給input中輸入任何的值。 但是在react中,我們對於input如果給定一個初始值,它是不會隨便進行輸入進行改變的,它必須同時繫結一個onChange事件。

<input type="text" value={this.state.value} onChange={(e) => this.setState({value: e.target.value})}>

在原生的表單中,textarea標籤的值是由其子元素決定的。例如:

<textarea value="mapbar_front" ></textarea>這個值是空的


<textarea>mapbar_front</textarea>這個值是有的mapbar_front

但是在react中,是由value屬性決定的。 同樣的,這個value屬性的改變,也需要使用onChange時間來進行更改value的狀態。

<textarea value="mapbar_front" ></textarea>

在react中,上面的value值是存在的,不過你不能改變文字框的值,你必須加上一個onChange事件來進行更改。

受控元件的意義,就是在react中,把input,textarea這一類的表單元素,使用onChange事件以及value屬性,動態跟蹤他們的值的改變。

無狀態元件

無狀態元件的意義,在於其良好的效能,它是用一個函式的方式進行表示一個元件的。

import React, { Component } from 'react';
export default function Hello(props) {
  return (
      <div>hello, {props.name}</div>
  );
}

無狀態元件,之所以由比較高的效能,是因為它自身少了一個元件的例項化的一個過程,它本身就是一個函式。

它自身的一切只與props相關,一切需要定義state的地方,你都應該抽離到容器元件上面,或者使用redux之類的東西,進行抽離。

它自身沒有this的概念,因為本身就是一個函式,而class型別的元件是要進行例項化的,所以會有this的概念。

在無狀態元件中,不能使用周期函式,這就要讓我們思考我們的資料結構,怎麼樣才算是顯得更加的高階。

無狀態元件,專注於UI層,它自身不會對業務邏輯進行處理,這就讓我們更好的理解component和page的關係問題。有助於我們進行元件分離。

高階元件

高階元件的本質,是一個函式,只不過這個函式的返回值,是一個class型別的元件。一個高階元件的基本示例如下:

function highComponent(MyComponent) {
  return class A extends Component {
      constructor(props) {
          super(props);
          this.state = {
              isShow: true
          }
      }
      componentDidMount() {
          this.setState({
            isShow: false,
          })
      }
      render() {
          return (
              <MyComponent isShow={this.state.isShow}></MyComponent>
          )
      }
  }
}

從上面的示例中可以看到,高階元件聚焦於業務層,不關心元件的UI層,所以在上面的示例中,我們可以把MyComponent這個傳遞進來的元件,寫成無狀態元件。

pureComponent 和 Component區別

首先,pureComponent是和shouldComponentUpdate這個周期函式相關,正常情況下,這個周期函式預設返回的是true,也就是任何props的改變,或者是任何的setState,都會導致介面的重新render。

pureComponent會改變shouldComponentUpdate的行為,它不再是返回一個true,它會對props和state進行一次淺比較,只有在不相等的情況下,再進行return 一個true,進行觸發render操作。

這個時候,如果是陣列型別,或者Object型別的資料發生變化,對於pureComponent而言,其實都是一樣的,不會觸發render。例如:

import React, { pureComponent } from 'react'
export default class A extends pureComponent{
   constructor(props) {
       super(props);
       this.state = {
           name: {
               value: 'mapbar'
           }
       }
       this.click = this.click.bind(this);
   }
   click() {
       this.state.name.value = 'mapbar_front';
      this.setState({
          name: this.state.name
      })
   }
   
  render() {
      return (
          <div onClick={this.click}>{this.state.name}</div>
      )
  }
}

以上的例子,不會觸發render,導致name的值一直是mapbar。