React——學習總結

簡單開始例子

ReactDOM.render(                   //React DOM 得render方法
  <h1>Hello, world!</h1>,          //渲染到html DOM節點得react元素
  document.getElementById('root')  //獲取html頁面得DOM節點
);

JSX

JSX, 一種 JavaScript 的語法擴展 React.createElement(component, props, ...children)得語法糖,因此須要先引用 React變量。 咱們推薦在 React 中使用 JSX 來描述用戶界面。JSX 乍看起來可能比較像是模版語言,但事實上它徹底是在 JavaScript 內部實現的。

一、JSX中使用JavaScript 表達式用大括號{}包起來;
二、if 或者 for 語句裏使用 JSX,將它賦值給變量,看成參數傳入,做爲返回值均可以;
三、JSX 換行和縮進時,代碼的外面擴上一個小括號,這樣能夠防止 分號自動插入 的 bug;
四、JSX 標籤是閉合式的;
五、camelCase 小駝峯命名 來定義屬性的名稱 className,backGround;
六、全部的內容在渲染以前都被轉換成了字符串,有效地防止 XSS(跨站腳本) 攻擊;
七、註釋語法:{/**/}
八、JSX 標籤名不能爲一個表達式,能夠先賦值給一個變量。
九、沒有給屬性傳值,它默認爲 truehtml

const element = (//換行用小括號括起來
  <div>
    <h1 className={aclass}>Hello!</h1> {/*屬性用小駝峯命名方式,變量aclass用{}括起來*/}
    <h2>{2+2}</h2>                     {/*js表達式用{}括起來*/}
  </div>
);
//能夠用點表示法來引用 React 組件
import React from 'react';
const MyComponents = {//一個模塊包含多個組件。
  DatePicker: function DatePicker(props) {
    return <div>Imagine a {props.color} datepicker here.</div>;
  }
}

function BlueDatePicker(props) {

  return <MyComponents.DatePicker color="blue" checked />;//點表示法 checked 值爲true
  //return <MyComponents[props.componentTtye] color="blue" />;錯誤:JSX 標籤名不能爲一個表達式
  //const componentType = MyComponents[props.componentTtye] ;return <componentType color="blue" />  //正確。
}

元素渲染

一、元素是構成 React 應用的最小單位;
二、大多數React應用只會調用一次 ReactDOM.render();
三、React DOM 首先會比較元素內容前後的不一樣,而在渲染過程當中只會更新改變了的部分;

組件 & Props

一、組件得含義與定義react

組件能夠將UI切分紅一些的獨立的、可複用的部件,從概念上看就像是 函數,它能夠接收任意的參數(稱之爲「props」),全部的React組件必須像 純函數那樣使用它們的props( 不可修改)。並 返回一個須要在頁面上展現的 React元素
//函數定義組件
function Welcome(props) {//參數props
  return <h1>Hello, {props.name}</h1>;//返回react 元素
}
//ES6 class定義組件
class Welcome extends React.Component { //擴展ES6類React.Component
  render() {//render()函數體
    return <h1>Hello, {this.props.name}</h1>;
  }
}
當React遇到的元素是用戶自定義的組件,它會將 JSX屬性做爲單個對象(props)傳遞給該組件,這個對象稱之爲「 props」。組件名 首字母大寫,使用該組件時必須 定義或引入它。
function Welcome(props) {              //自定義組件
  return <h1>Hello, {props.name}</h1>;//props={name:"Sara"}
}

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,                            //元素爲自定義組件Welcome
  document.getElementById('root')
);

二、組合組件express

組件能夠在它的輸出中引用其它組件,React應用中,按鈕、表單、對話框、整個屏幕的內容等,這些一般都被表示爲組件。組件的返回值只能有一個根元素。
function App() {
  return (
    <div>{/*一個根元素*/}
      <Welcome name="Sara" />{/*引用自定義Welcome組件*/}
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

State & 生命週期

一、state數組

一、局部狀態State:一個功能只適用於類定義組件;
二、 構造函數(constructor)是惟一可以初始化 this.state 的地方;
三、應當使用 setState()更新局部狀態,而不是直接更改this.state得值;
四、this.props 和 this.state 多是 異步更新,不能用他們來計算this.state得下一個值,應該用
setState回調函數得方式傳入參數 (prevState, props),return一個對象;
六、當你調用 setState() 時,React 將你提供的對象合併到當前狀態,更新其中一個(state.name)屬性時,會將該屬性合併到this.state對象中;
七、 自頂向下單向數據流,任何狀態始終由某些特定組件全部,而且從該狀態導出的任何數據或 UI 只能影響樹中 下方的組件

二、生命週期異步

掛載:組件加載到DOM中,
卸載:生成的DOM被移除。
生命週期鉤子:componentWillUnmount()掛載前, componentDidMount()掛載後
class Clock extends React.Component {
  constructor(props) {                //基礎構造函數
    super(props);                     //傳遞props
    this.state = {date: new Date()};  //惟一初始化this.state得地方
  }

  componentDidMount() {//react 元素添加到DOM中後
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {//react 元素即將從DOM中刪除
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({  //更改state得值
      date: new Date()
    });
   /*回調函數得方式更改state得值
     this.setState((prevState, props) => ({
      date: prevState.date + 1
    }));*/
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>{/*每次state更新時調用render方法從新渲染值*/}
      </div>
    );
  }
}

ReactDOM.render(//初次調用render渲染clock組件到DOM中
  <Clock />,
  document.getElementById('root')
);

事件處理

一、React事件綁定屬性的命名採用 駝峯式寫法,而不是小寫;
二、若是採用 JSX 的語法你須要 傳入一個函數做爲事件處理函數,而不是一個字符串(DOM元素的寫法);
三、在 React 中另外一個不一樣是你不能使用返回 false 的方式阻止默認行爲。你必須明確的使用 e.preventDefault();
四、類的方法默認是不會綁定 this,沒有在方法後面添加 (),要爲這個方法綁定 this,( 構造函數中綁定,屬性初始化器法, 箭頭函數), 箭頭函數,若是這個回調函數做爲一個屬性值傳入低階組件,這些組件可能會進行額外的從新渲染。建議選用其餘兩種方法。
五、傳參數:參數 e 做爲 React 事件對象將會被做爲第二個參數進行傳遞。經過 箭頭函數的方式, 事件對象e必須 顯式的進行傳遞,可是經過 bind 的方式,事件對象以及更多的參數將會被 隱式的進行傳遞。
class LoggingButton extends React.Component {
  // This syntax ensures `this` is bound within handleClick.
  // Warning: this is *experimental* syntax.
  handleClick = () => {//屬性初始化器法綁定this
    console.log('this is:', this);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}
class LoggingButton extends React.Component {
/*構造函數中綁定this
    constructor(props) {
        super(props);
        // This binding is necessary to make `this` work in the callback
        this.handleClick = this.handleClick.bind(this);
   }*/
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // This syntax ensures `this` is bound within handleClick
    return (
      <button onClick={(e) => this.handleClick(e,id)}>{/*箭頭函數方法,用構造函數中綁定this時可直接調用this.handleClick*/}
        Click me
      </button>
    );
  }
}

條件渲染

一、使用 JavaScript 操做符 if 或條件運算符來建立表示當前狀態的元素 知足條件return元素;
二、聲明一個變量用於存儲元素,渲染組件得其中一部分元素;
三、與運算符 &&:用花括號包裹代碼在 JSX 中 嵌入任何表達式 ,也包括 JavaScript 的邏輯與 &&,JavaScript 中,true && expression 老是返回 expression,而 false && expression 老是返回 false,若是條件是 true,&& 右側的元素就會被渲染,若是是 false,React 會忽略並跳過它;
四、三目運算符:condition ? true : false;
五、阻止組件渲染 :render 方法返回 null,可是 生命週期得方法依然能夠回調
function WarningBanner(props) {
  if (!props.warn) {
    return null;    //返回null不渲染元素
  }
 const a = <a>超連接</a>;//存儲元素到變量
  if (props.warn == 「a」) {//if條件句 return元素,tia'jian渲染
    return a;    
  }

  return (
    <div className="warning">
      Warning!
    </div>
  );
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true}
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }

  handleToggleClick() {
    this.setState(prevState => ({
      showWarning: !prevState.showWarning
    }));
  }

  render() {
    return (
      <div>
        <WarningBanner warn={this.state.showWarning} />
        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? 'Hide' : 'Show'}{/*三目運算符選擇渲染文本*/}
        </button>
        {this.props.warn=="b" && <a>b超連接</a>} // &&條件渲染
      </div>
    );
  }
}

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

列表 & Keys

一、map()
二、當你建立一個元素時,必須包括一個特殊的 key 屬性。key是惟一得標識,數據裏面得id或索引index,key應該綁定在循環得組件上而不是DOM元素上 key應該在數組的上下文中被指定
三、兩個不一樣的數組時,咱們可使用相同的鍵;
四、key會做爲給React的提示,但不會傳遞給你的組件,傳遞給組件必須賦值在組件得屬性上;
五、也可在JSX中使用map();
function ListItem(props) {
  // 對啦!這裏不須要指定key:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 又對啦!key應該在數組的上下文中被指定
    <ListItem key={number.toString()}
              value={number} />

  );
  return (
    <ul>
      {listItems}
      {numbers.map((number)=>
          <ListItem value={number} key={index}/> 
      )
      }
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

表單

一、受控組件(<input>,<textarea>, <select>): 每一個狀態的改變都有一個與之相關的處理函數,使react變成一種單一數據源的狀態,表單值爲state的屬性值,更改時調用事件更改state值。經過傳入一個value屬性來實現對組件的控制;
二、<textarea>:value屬性來text內容;
三、select 標籤:用value值表明選中的內容;
四、處理多個受控的input元素時,能夠經過給每一個元素添加一個name屬性,來讓處理函數根據 event.target.name的值來選擇作什麼。
class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value; //判斷type
    const name = target.name;  //根據target.name來設定值。

    this.setState({
      [name]: value
    });
  }

  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}

狀態提高

一、 經過將state數據提高至離須要這些數據的組件最近的父組件來完成的。這就是所謂的狀態提高;
二、讓組件「受控」,讓組件收一個一個屬性值爲父組件得函數名。可在組件內調用該函數,該函數使用setState();
三、在React應用中,對應任何可變數據理應只有一個單一「數據源」。一般,狀態都是首先添加在須要渲染數據的組件中。此時,若是另外一個組件也須要這些數據,你能夠將數據提高至離它們最近的父組件中。你應該在應用中保持 自上而下的數據流,而不是嘗試在不一樣組件中同步狀態。

組合 vs 繼承

一、React 具備強大的組合模型,咱們建議使用組合而不是繼承來複用組件之間的代碼;
二、包含關係:不知道子組件是什麼(Sidebar 或 Dialog),children(this.props.children) 屬性將子元素直接傳遞到輸出,該組件包含的其餘元素即爲children屬性得值,或者將元素賦值給組件得自定義屬性;
三、特殊實例:經過配置屬性用較特殊的組件來渲染較通用的組件;
function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
      {props.children}
    </FancyBorder>
  );
}

class SignUpDialog extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSignUp = this.handleSignUp.bind(this);
    this.state = {login: ''};
  }

  render() {
    return (
      <Dialog title="Mars Exploration Program"
              message="How should we refer to you?">
        <input value={this.state.login}
               onChange={this.handleChange} />

        <button onClick={this.handleSignUp}>
          Sign Me Up!
        </button>
      </Dialog>
    );
  }

  handleChange(e) {
    this.setState({login: e.target.value});
  }

  handleSignUp() {
    alert(`Welcome aboard, ${this.state.login}!`);
  }
}
相關文章
相關標籤/搜索