React中,推出了一種新的語法取名爲JSX,它給了JS中寫HTML標籤的能力,不須要加引號。JSX的語法看起來是一種模板,然而它在編譯之後,會轉成JS語法,只是書寫過程當中的語法糖。
JSX的解析器會幫咱們讀取這種語法並加以處理。
下面是一個簡單的例子。javascript
const element = <h1 className="greeting">Hello, world!</h1>;
其實至關於以下的代碼:html
const element = React.createElement({ 'h1', {className: 'greeting'}, 'Hello, world!', 'Xxx' })
第一個參數是類型,能夠是HTML標籤,也能夠是React組件;第二個參數是props對象;第三個之後參數是children,會按照傳入順序依次排列。
固然第三個參數也能夠傳入數組,若是第三個參數傳入數組,則後面再傳入其餘子節點,就會報錯。
JSX提供了一種HTML和JS混合編寫的能力。在須要使用JS表達式的地方,用一組花括號包裹起來便可:java
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實際上是語法糖,因此若是要循環嵌入列表,能夠直接將列表傳進來:react
const numbers = [1, 2, 3, 4, 5]; const listItems = numbers.map((number) => <li>{number}</li> ); ReactDOM.render( <ul>{listItems}</ul>, document.getElementById('app') );
在控制檯中會看到這樣的報錯:es6
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.app
組件能夠看作是一個函數,指定了輸入(props),就會給出輸出(一個React元素)。
建立組件有兩種方法:
1.函數dom
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相似於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。
1.用來初始化props和state。
2.是惟一能夠直接修改state的地方。
1.當state須要從props初始化時使用
2.儘可能不要使用:由於維護二者的一致會增長複雜度
3.每次render前都會被調用
4.典型場景:表單控件獲取默認值
不能缺乏的,它實際上決定了組件到底要渲染成什麼樣子。
1.在UI渲染完成以後觸發
2.只執行一次
3.一般在這個方法裏觸發Ajax請求等操做。
有三種狀況會觸發update。
props發生了改變,setState執行,forceUpdate執行。
前兩種很少說,第三個forceUpdate觸發的場景比較少見,若是Render方法使用了props和state之外的數據,就須要這個方法。
這裏是一個例子。
1.決定virtual dom是否會重繪
2.通常能夠用pure component自動實現
3.這個方法用來作性能優化相關的操做。有的時候state和props的更新其實不會影響dom的展現,沒有必要再次渲染DOM。
1.更新DOM前被觸發,state已經更新
2.它能夠將以前DOM的狀態傳遞給componentDidUpdate,而後進行計算處理後更新DOM。
這裏一個例子。
1.每次UI更新後都會調用
2.props或者state修改後都會觸發
這個階段只會觸發一個方法。
1.只調用一次
2.能夠在這個方法裏清除計時器,關閉一些鏈接等。
以上是JSX、組件概念、props、state、生命週期的介紹。 感謝閱讀。