react學習

react

JSX

在 JSX 語法中,你可以在大括號內(nèi)放置任何有效的 JavaScript 表達式。
例如,2 + 2,user.firstName 或 formatName(user) 都是有效的 JavaScript 表達式。

為了便于閱讀,我們會將 JSX 拆分為多行,建議將內(nèi)容包裹在括號中

你可以在 if 語句和 for 循環(huán)的代碼塊中使用 JSX,將 JSX 賦值給變量,把 JSX 當作參數(shù)傳入,以及從函數(shù)中返回 JSX

你可以通過使用引號,來將屬性值指定為字符串字面量:

const element = <div tabIndex="0"></div>;

也可以使用大括號,來在屬性值中插入一個 JavaScript 表達式:

const element = <img src={user.avatarUrl}></img>;

在屬性中嵌入 JavaScript 表達式時,不要在大括號外面加上引號。你應該僅使用引號(對于字符串值)或大括號(對于表達式)中的一個,對于同一屬性不能同時使用這兩種符號。

注意:
因為 JSX 語法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase(小駝峰命名)來定義屬性的名稱,而不使用 HTML 屬性名稱的命名約定。


JSX 防止注入攻擊

React DOM 在渲染所有輸入內(nèi)容之前,默認會進行轉(zhuǎn)義。它可以確保在你的應用中,永遠不會注入那些并非自己明確編寫的內(nèi)容。所有的內(nèi)容在渲染之前都被轉(zhuǎn)換成了字符串。這樣可以有效地防止 XSS(cross-site-scripting, 跨站腳本)攻擊。


JSX 表示對象

Babel 會把 JSX 轉(zhuǎn)譯成一個名為 React.createElement() 函數(shù)調(diào)用。


const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
  )
  
  //兩種代碼完全等效
const element = React.createElement(
//接受三個參數(shù),標簽名,屬性參數(shù)對象,子元素
  'h1',
  {className: 'greeting'},
  'Hello, world!'
  )

這些對象被稱為 “React 元素”。它們描述了你希望在屏幕上看到的內(nèi)容。React 通過讀取這些對象,然后使用它們來構(gòu)建 DOM 以及保持隨時更新。

元素渲染

元素是構(gòu)成 React 應用的最小磚塊

與瀏覽器的 DOM 元素不同,React 元素是創(chuàng)建開銷極小的普通對象。React DOM 會負責更新 DOM 來與 React 元素保持一致。


僅使用 React 構(gòu)建的應用通常只有單一的根 DOM 節(jié)點

<div id="root"></div>

想要將一個 React 元素渲染到根 DOM 節(jié)點中,只需把它們一起傳入 ReactDOM.render():

const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));

在實踐中,大多數(shù) React 應用只會調(diào)用一次 ReactDOM.render()

React 只更新它需要更新的部分.

React DOM 會將元素和它的子元素與它們之前的狀態(tài)進行比較,并只會進行必要的更新來使 DOM 達到預期的狀態(tài)。

考慮 UI 在任意給定時刻的狀態(tài),而不是隨時間變化的過程,能夠消滅一整類的 bug

組件&Props

獨立,可復用,單獨構(gòu)思

組件,從概念上類似于 JavaScript 函數(shù)。它接受任意的入?yún)ⅲ?“props”),并返回用于描述頁面展示內(nèi)容的 React 元素。


函數(shù)組件與class組件

用函數(shù)定義組件

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

用ES6語法的class定義組件:

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

上面兩者等效

如何將函數(shù)組件轉(zhuǎn)換成class組件:

  1. 創(chuàng)建一個同名的 ES6 class,并且繼承于 React.Component。
  2. 添加一個空的 render() 方法。
  3. 將函數(shù)體移動到 render() 方法之中。
  4. 在 render() 方法中使用 this.props 替換 props。
  5. 刪除剩余的空函數(shù)聲明。

當 React 元素為用戶自定義組件時,它會將 JSX 所接收的屬性(attributes)轉(zhuǎn)換為單個對象傳遞給組件,這個對象被稱之為 “props”。

關(guān)鍵詞:props

組合組件

組件可以在其輸出中引用其他組件。
用同一組件來抽象出任意層次的細節(jié)。

通常來說,每個新的 React 應用程序的頂層組件都是 App 組件。

Props的只讀性

組件無論是使用函數(shù)聲明還是通過 class 聲明,都決不能修改自身的 props。

純函數(shù):不會嘗試更改入?yún)ⅲ叶啻握{(diào)用下相同的入?yún)⑹冀K返回相同的結(jié)果。

React 非常靈活,但它也有一個嚴格的規(guī)則:所有 React 組件都必須像純函數(shù)一樣保護它們的 props 不被更改。

State&生命周期

State 與 props 類似,但是 state 是私有的,并且完全受控于當前組件。


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

  render() {
    return (
      <div>        
        <h1>Hello, world!</h1>        
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>             </div>
    )
  }
 }
 
 
ReactDOM.render(  
<Clock />, 
document.getElementById('root')
)

Class 組件應該始終使用 props 參數(shù)來調(diào)用父類的構(gòu)造函數(shù)。

class 組件聲明一些特殊的方法,當組件掛載或卸載時就會去執(zhí)行這些方法,叫做“生命周期方法”

componentDidMountcomponentWillUnmount

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

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

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

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

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

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

正確地使用State

  • 不要直接修改State,而是使用setState();
    構(gòu)造函數(shù)是唯一可以給 this.state 賦值的地方
  • State 的更新可能是異步的
  • State 的更新會被合并
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

讓setState()接受一個函數(shù)而不是一個對象。

// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

//普通函數(shù)寫法
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});

數(shù)據(jù)是向下流動的

組件可以選擇把它的 state 作為 props 向下傳遞到它的子組件中。

任何的 state 總是所屬于特定的組件,而且從該 state 派生的任何數(shù)據(jù)或 UI 只能影響樹中“低于”它們的組件。

如果你把一個以組件構(gòu)成的樹想象成一個 props 的數(shù)據(jù)瀑布的話,那么每一個組件的 state 就像是在任意一點上給瀑布增加額外的水源,但是它只能向下流動。

事件處理

  • React 事件的命名采用小駝峰式(camelCase),而不是純小寫
  • 使用 JSX 語法時你需要傳入一個函數(shù)作為事件處理函數(shù),而不是一個字符串

在 React 中另一個不同點是你不能通過返回 false 的方式阻止默認行為。你必須顯式的使用 preventDefault。


class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 為了在回調(diào)中使用 `this`,這個綁定是必不可少的    this.handleClick = this.handleClick.bind(this);  }

  handleClick() {    this.setState(state => ({      isToggleOn: !state.isToggleOn
    }));  }
  render() {
    return (      <button onClick={this.handleClick}>        {this.state.isToggleOn ? 'ON' : 'OFF'}      </button>
    );
  }}

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

你必須謹慎對待 JSX 回調(diào)函數(shù)中的 this,在 JavaScript 中,class 的方法默認不會綁定 this。如果你忘記綁定 this.handleClick 并把它傳入了 onClick,當你調(diào)用這個函數(shù)的時候 this 的值為 undefined.

使用 class fields 正確的綁定回調(diào)函數(shù):


class LoggingButton extends React.Component {  // 此語法確保 `handleClick` 內(nèi)的 `this` 已被綁定。  // 注意: 這是 *實驗性* 語法。  
handleClick = () => {    console.log('this is:', this);  }
  render() {
    return (
      <button onClick={this.handleClick}>        Click me      </button>
    );
  }}

或者在回調(diào)中使用箭頭函數(shù):


class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {   
  // 此語法確保 `handleClick` 內(nèi)的 `this` 已被綁定。   
  return (      
  <button onClick={(e) => this.handleClick(e)}>        Click me      
  </button>
    );
  }}

向事件處理程序傳遞參數(shù)

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

上述兩種方式是等價的,分別通過箭頭函數(shù)和 Function.prototype.bind 來實現(xiàn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 3. JSX JSX是對JavaScript語言的一個擴展語法, 用于生產(chǎn)React“元素”,建議在描述UI的時候...
    pixels閱讀 2,972評論 0 24
  • 安裝: 概述 React起源于FaceBook的內(nèi)部項目,因為該公司對市場上所有的JavaScript MVC框架...
    姒沝無痕閱讀 799評論 0 0
  • 官網(wǎng)地址https://facebook.github.io/react/docs/hello-world.htm...
    pixels閱讀 741評論 0 6
  • React 核心思想 —— 組件化React 將界面分成了一個個組件,通過組件的組合、嵌套構(gòu)成頁面。其中,組件可復...
    sylvia_yue閱讀 1,128評論 1 2
  • Learn from React 官方文檔 一、Rendering Elements 1. Rendering a...
    恰皮閱讀 2,726評論 2 3

友情鏈接更多精彩內(nèi)容