1. 程式人生 > >react教程(一)JSX語法、組件概念、生命周期介紹

react教程(一)JSX語法、組件概念、生命周期介紹

app .org react教程 sna 輸入 卸載 war fun 獲取

JSX

React中,推出了一種新的語法取名為JSX,它給了JS中寫HTML標簽的能力,不需要加引號。JSX的語法看起來是一種模板,然而它在編譯以後,會轉成JS語法,只是書寫過程中的語法糖。
JSX的解析器會幫我們讀取這種語法並加以處理。
下面是一個簡單的例子。

const element = <h1 className="greeting">Hello, world!</h1>;

其實相當於如下的代碼:

const element = React.createElement({
  ‘h1‘,
  {className: ‘greeting‘},
  ‘Hello, world!‘,
  ‘Xxx‘
})

第一個參數是類型,可以是HTML標簽,也可以是React組件;第二個參數是props對象;第三個以後參數是children,會按照傳入順序依次排列。
當然第三個參數也可以傳入數組,如果第三個參數傳入數組,則後面再傳入其他子節點,就會報錯。
JSX提供了一種HTML和JS混合編寫的能力。在需要使用JS表達式的地方,用一組花括號包裹起來即可:

function formatName(user) {
  return user.firstName + ‘ ‘ + user.lastName;
}

const user = {
  firstName: ‘Harper‘,
  lastName: ‘Perez‘
};

const element = (
  <h1 className="test">
    Hello, {formatName(user)}!
  </h1>
);

ReactDOM.render(
  element,
  document.getElementById(‘app‘)
);

由於class在js中關鍵字,所以使用className去替代。
上面說到了JSX其實是語法糖,所以如果要循環嵌入列表,可以直接將列表傳進來:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}</li>
);
ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById(‘app‘)
);

在控制臺中會看到這樣的報錯:

warning.js:33 Warning: Each child in an array or iterator should have a unique "key" prop.

這是由於react使用virtual dom來渲染真實節點,在列表渲染時,如果每個item沒有對應的key,react處理起增刪改時就會很慢,所以,渲染列表時,最好給每一個item增加一個唯一的key。

const listItems = numbers.map((number, index) =>
  <li key={index}>{number}</li>
);

組件

React中最重要的概念就是組件。

Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called “props”) and return React elements describing what should appear on the screen.

組件可以看做是一個函數,指定了輸入(props),就會給出輸出(一個React元素)。
創建組件有兩種方法:
1.函數

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

2.es6的類

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

第二種方法創建的組件,可以擁有內部狀態(state)和生命周期函數。
如果只是展示信息,沒有復雜的操作,可以選擇第一種函數方法。如果組件比較復雜,並且需要在不同的時期做初始化或者銷毀等工作,就要采用第二種ES6類方法。

狀態(State)

State類似於props,但它是組件私有的並且完全由組件控制。
下面我們結合一個Clock類來演示State的概念。

import React, {Component} from ‘react‘;

export default class Clock extends Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

在這個組件裏,Clock就擁有了自己的狀態,而不是從外界發生傳入。接下來我們增加一個定時器的功能,來引入生命周期。

import React, {Component} from ‘react‘;

export default class Clock extends Component {
  ...

  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID)
  }

  tick () {
    this.setState({date: new Date()})
  }
  ...
}

註意:在React中,調用setState方法去修改state,會觸發View視圖層的修改,直接設置state就不會觸發state的修改。
上面引入了兩個生命周期方法:componentDidMount , componentWillUnmount
componentDidMount 會在組件掛載到DOM節點上之後觸發,而 componentWillUnmount 會在組件從節點上移除以後觸發。
React還有很多生命周期方法,下面做一個詳細的說明。

生命周期

在React中,一個組件可能會經歷創建、掛載、更新、卸載、銷毀這些事件,React為我們提供了鉤子函數來在這些事件觸發時進行操作。
他的生命周期可以分為三大部分:
創建更新銷毀
創建組件並將其插入DOM時,下面的方法會依次觸發

constructor()
static getDerivedStateFromProps()
render()
componentDidMount()

更新時,將會觸發

static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()

卸載時,觸發

componentWillUnmount()

為了更加直觀的查看生命周期方法,可以參考這張圖:
技術分享圖片
圖片來源:http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/。
Render階段,把一些state和props計算執行。
Commit階段就是把React組件插入到真實DOM節點上,這個時候可以使用DOM。
而Pre-commit階段就是在插入真實DOM之前,這個階段可以讀取DOM。

創建時

constructor

1.用來初始化props和state。
2.是唯一可以直接修改state的地方。

getDerivedStateFromProps

1.當state需要從props初始化時使用
2.盡量不要使用:因為維護兩者的一致會增加復雜度
3.每次render前都會被調用
4.典型場景:表單控件獲取默認值

render

不能缺少的,它實際上決定了組件到底要渲染成什麽樣子。

componentDidMount

1.在UI渲染完成之後觸發
2.只執行一次
3.通常在這個方法裏觸發Ajax請求等操作。

更新時

有三種情況會觸發update。
props發生了改變,setState執行,forceUpdate執行。

forceUpdate

前兩種不多說,第三個forceUpdate觸發的場景比較少見,如果Render方法使用了props和state以外的數據,就需要這個方法。
這裏是一個例子。

shouldComponentUpdate

1.決定virtual dom是否會重繪
2.一般可以用pure component自動實現
3.這個方法用來做性能優化相關的操作。有的時候state和props的更新其實不會影響dom的展示,沒有必要再次渲染DOM。

getSnapshotBeforeUpdate

1.更新DOM前被觸發,state已經更新
2.它可以將之前DOM的狀態傳遞給componentDidUpdate,然後進行計算處理後更新DOM。
這裏一個例子。

componentDidUpdate

1.每次UI更新後都會調用
2.props或者state修改後都會觸發

卸載時

這個階段只會觸發一個方法。

componentWillUnmount

1.只調用一次
2.可以在這個方法裏清除計時器,關閉一些連接等。

以上是JSX、組件概念、props、state、生命周期的介紹。
感謝閱讀。

react教程(一)JSX語法、組件概念、生命周期介紹