1. 程式人生 > 實用技巧 >React入門學習筆記

React入門學習筆記

React學習筆記

安裝

1、通過js檔案引入React的js檔案

2、npm部署React環境

詳情請參考官方文件

元件

Props資料傳遞

資料可以通過Props在兩個元件間傳遞(父元件流向子元件)

class Square extends React.Component {
    render() {
        return (
            <button className="square">
                {this.props.value}  
            </button>
        );
    }
}

class Board extends React.Component {
    renderSquare(i) {
        return <Square value={i} />; // 這裡就會把i傳遞給Square
    }
    ...
}

初始化

class Square extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: null,
        }
    }

    render() {
        return (
            <button className="square" 
                    onClick={()=>this.setState({value:'X'}) }>
                {this.state.value}  
            </button>
        );
    }
}

這裡的constructor()初始化了props,state.value=null;當點選後,state.value=X;

每當state發生變化,就會重新渲染子元件。

簡單的JSX

const element = <h1>Hello,React!</h1> ;

JSX是Javascript的語法擴充套件,在React配合使用JSX可以很好的描述UI。JSX具備JavaScript的全部功能。

JSX可以生成React元素,將這些元素渲染為DOM。

JSX語法中,可以在大括號內放置任何有效的JS表示式;

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

const element = <h1>Hello,React!</h1>;

ReactDOM.render(element, document.getElementById('root'));

React元素是不可變物件,建立後無法改變Ta的子元素/屬性;想要改變元素只有重新渲染建立一個許可權的元素並傳入ReactDOM.render()

ReactDOM會將元素和子元素與ta們的狀態進行比較,並只會進行必要的更新來使DOM達到預期。

元件

元件類似於一個類物件,將可獨立且複用的程式碼片段進行獨立構造成一個元件,呼叫該元件即可實現程式碼複用。

函式元件與class元件

  • 函式元件
function Welcome(props) {
    return ....
}

welocme()函式是一個React函式元件,接收帶有資料的props物件並返回一個React元素。

  • class元件
class Welcome extends React.Component {
    render() {
        return ...
    }
}

渲染元件

React元素支援使用者自定義的元件:

const element = <Welcome name="demo" />

React元素為自定義元件,JSX所接收的屬性、子元件轉換為單個物件props傳遞給元件。

class Welcome extends React.Component {
    render() {
        return <p>{props.name} -- {props.value}</p>;
    }
}

const element = <Welcome name="demo" value="demo.." />

React會將以小寫字母開頭的元件視為原生DOM標籤

渲染輸出顯示,元件可以引用其它元件。

class Welcome extends React.Component {
    render() {
        return <p>{props.name} -- {props.value}</p>;
    }
}

class App() extends React.Component {
    render() (
        <div>
            <Welcome name="one" value="1"/>
            <Welcome name="two" value="2"/>
        </div>
    );
}

ReactDOM.render(<App />, document.getElementById('root'));

提取元件

如果我們寫了一個非常非常重的元件,則可以依照層次結構提取元件變為多個小元件。

function Comment(props) {
    return (
        <div className="Comment">
            <div className="UserInfo">
                <img className="Avatar"
                    src={props.author.avatarUrl}
                    alt={props.author.name}
                />
                <div className="UserInfo-name">
                    {props.author.name}
                </div>
            </div>
            <div className="Comment-text">
                {props.text}
            </div>
            <div className="comment-date">
                {formatDate(props.date)}
            </div>
        </div>
    );
}

經過元件提取後如下

function Avatar(props) {
    return (
        <img className="Avatar"
            src={props.user.avatarUrl}
            alt={props.user.name}
        />
    )
}

function UserInfo(props) {
    return (
        <div className="UserInfo">
            <Avatar user={props.user} />
            <div className="UserInfo-name">
                {props.user.name}
            </div>
        </div>
    )
}

function Comment(props) {
    return (
        <div className="Comment">
            <UserInfo user={props.author} />
            <div className="Comment-text">
                {props.text}
            </div>
            <div className="comment-date">
                {formatDate(props.date)}
            </div>
        </div>
    );
}

元件無論如何都不能修改自身的props;React靈活允許接收自定義的傳參,但絕不允許props被更改。

state與生命週期

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Clock extends React.Component {
    // class建構函式。為this.state賦值
    constructor(props) {
        super(props);
        this.state = {
            date : new Date()
        };
    }
    // 元件被渲染到DOM後執行(掛載執行)
    componentDidMount() {
        // 設定計時器
        this.timerID = setInterval(
            () => this.tick(),
            1000
        );
    }
    // 元件從DOM移除後執行(解除安裝執行)
    componentWillUnmount() {
        // 清楚計時器
        clearInterval(this.timerID);
    }
    

    tick() {
        // 修改state
        this.setState({
            date : new Date()
        });
    }

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

}

ReactDOM.render(
    <Clock />,
    document.getElementById('root')
);

  • 正確使用State

1、不能直接修改State,需要呼叫this.setState()方法來修改。

2、State屬於非同步更新、合併更新,因為是呼叫同一個方法來更新資料,所以會存在合併非同步更新的情況。

3、資料是向下流動的,子無法直接向父傳遞資料;每一個元件的state是區域性封裝,如果需要可以作為props向下傳遞到子元件。

事件處理

1、React的事件命名採用小駝峰式

2、使用JSX語法時,需要傳入一個函式作為事件處理函式而不是字串

3、阻止事件不可返回false方式,必須顯式的使用preventDefault

條件渲染

React使用JS的運算子去建立元素來表示狀態。

可以使用變數來儲存元素,有條件的渲染元件的一部分內容。

列表和key

我們可以使用map去遍歷一個數組然後返回一個帶有li標籤的“列表”陣列,我們則可以成功的渲染一個列表;但是由於React的約束要求,我們的列表元素中必須包括一個特殊的key屬性。

key幫助React識別元素的改變(增/刪/改),故此需要給陣列中的沒一個li元素一個確定的同層唯一標識。

受控元件

在HTML表單元素中,表單元素會自己維護自己的狀態而在React中可變狀態通常是有state屬性控制的,並且只可以使用setState()更新屬性;為了適應React的state成為“唯一資料來源”,渲染表單的元件還控制著輸入過程中表單發生的操作,被React以這種方式控制取制的表單輸入元素稱之為“受控元件”。

React文件中也指出React對錶單的受控元件處理比較煩雜,而且存在非受控元件;官方給出了推薦[Formik]