react筆記

react中文文檔
以下文字均為看文檔后的筆記

用引號來定義以字符串為值的屬性

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

用大括號來定義以 JavaScript 表達式為值的屬性(使用了大括號包裹的 JavaScript 表達式時就不要再到外面套引號了。因為JSX 會將引號當中的內容識別為字符串而不是表達式)

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

JSX使用 camelCase 小駝峰命名 來定義屬性的名稱
JSX所有的內容在渲染之前都被轉換成了字符串。這樣可以有效地防止XSS攻擊。
Babel 轉譯器會把 JSX 轉換成一個名為 React.createElement() 的方法調用。
//原先
const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
//轉換后
const element = React.createElement(
  'h1',//第一個是tagname
  {className: 'greeting'},//第二個是屬性,如果沒有則為null
  'Hello, world!'//第三個是內容即children,如果是嵌套的就會在這里循環下去
);
React 元素都是不可變的。當元素被創建之后,你是無法改變其內容或屬性的,更新界面的唯一辦法是創建一個新的元素,然后將它傳入 ReactDOM.render() 方法
React 只會更新必要的部分,React DOM 首先會比較元素內容先后的不同,而在渲染過程中只會更新改變了的部分
functional component和class component
當React遇到的元素是用戶自定義的組件,它會將JSX屬性作為單個對象傳遞給該組件,這個對象稱之為“props”。
const element = <Welcome name="Sara" />;
//這段中 name='Sara' 會作為參數即props:{name:'Sara'}傳入Welcome并調用Welcome
組件名稱必須以大寫字母開頭
組件嵌套時,頂部的組件返回值只能有一個根元素
State是組件自己私有的屬性,所以不同于props不能改變,可以通過調用setState()來改變state
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({ //setState()是唯一可以改變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')
);
數據自頂向下流動,組件可以選擇將其狀態作為屬性傳遞給其子組件,但是子組件無法知道其來源
<FormattedDate date={this.state.date} />
function FormattedDate(props) {
  return <h2>It is {props.date.toLocaleTimeString()}.</h2>;
}
在React中必須明確的使用 preventDefault 來阻止默認行為,不能使用返回false來阻止
class Clock extends React.Component {
    render(){
          return (
            <div>
              <a href="baidu.com" onClick={abc}>百度首頁</a>
              <h1>Hello, world!</h1>
            </div>
          );
    }
  }
  function abc(e){
    e.preventDefault()
    console.log('The link was clicked.')
    //return false //這段會無效,頁面依舊跳轉
  }
reactDom.render(
    <Clock/>,
    document.getElementById('root')
)
通過 bind 方式向監聽函數傳參,在類組件中定義的監聽函數,事件對象 e 要排在所傳遞參數的后面

fn(name,e){}

受控組件,在React中,可變的狀態通常保存在組件的狀態屬性中,并且只能用setState() 方法進行更新.
class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

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

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
//input的value存儲在state中,改變時調用setState,
在React中,<textarea>會用value屬性來代替,用法類似input.
<textarea value={this.state.value} onChange={this.handleChange} />
select標簽的selected是由select標簽上的value屬性置頂,而不是option
constructor(props) {
    super(props);
    this.state = {value: 'coconut'};

-------
<select value={this.state.value} onChange={this.handleChange}>
            <option value="grapefruit">Grapefruit</option>
            <option value="lime">Lime</option>
            <option value="coconut">Coconut</option>
            <option value="mango">Mango</option>
</select>
以上三種都十分類似,都是通過傳入一個value屬性來實現對組件的控制。
當你有處理多個受控的input元素時,你可以通過給每個元素添加一個name屬性,來讓處理函數根據 event.target.name的值來選擇做什么。
handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

    this.setState({
      [name]: value
    });
  }
//效果類似過濾
狀態提升,遇到幾個組件需要共用狀態數據的情況。這種情況下,將這部分共享的狀態提升至他們最近的父組件當中進行管理,即其中一個子組件變化時另一個子組件也會變,與之前不同的是,子組件的props將由父組件提供,包括change的方法,因為change是父組件的方法所以可以改變父組件的state,從而影響子組件
在應用中應保持自上而下的數據流,而不是嘗試在不同組件中同步狀態。
React 具有強大的組合模型,我們建議使用組合而不是繼承來復用組件之間的代碼。
JSX 標簽內的任何內容都將通過 children 屬性傳入組件。由于組件在一個 <div> 內渲染了 {props.children},所以被傳遞的所有元素都會出現在最終輸出中。屬性不限于children,也可以是自己約定的屬性
function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}

這時 children屬性為
<h1 className="Dialog-title">
        Welcome
</h1>
<p className="Dialog-message">
        Thank you for visiting our spacecraft!
</p>
在較為簡單的例子中,通常自頂向下更容易,而在較大的項目中,自底向上會更容易并且在你構建的時候有利于編寫測試

react key概述

react中的key屬性,它是一個特殊的屬性,它是出現不是給開發者用的(例如你為一個組件設置key之后不能獲取組件的這個key props),而是給react自己用的。

簡單來說,react利用key來識別組件,它是一種身份標識標識,就像我們的身份證用來辨識一個人一樣。每個key對應一個組件,相同的key react認為是同一個組件,這樣后續相同的key對應組件都不會被創建

users: [
{id:1,name: '張三'},
{id:2, name: '李四'}, 
{id: 2, name: "王五"}
]

比如這樣的數據中,王五不會被渲染,主要是因為react根據key認為李四和王五是同一個組件,導致第一個被渲染,后續的會被丟棄掉。

key不是用來提升react的性能的,不過用好key對性能是有幫助的的。

參考資料
React之key詳解

大寫開頭的 JSX 標簽表示一個 React 組件。這些標簽將會被編譯為同名變量并被引用,所以如果你使用了 <Foo /> 表達式,則必須在作用域中先聲明 Foo 變量。
React 會將小寫開頭的標簽名認為是 HTML 原生標簽
你不能使用表達式來直接作為 React 元素的標簽
const components = {
  photo: PhotoStory,
  video: VideoStory
};

 const SpecificStory = components[props.storyType];
  return <SpecificStory story={props.story} />;
//比如這樣先賦值給SpecificStory這樣的大寫開頭的變量
if 語句和 for 循環在 JavaScript 中不是表達式,因此它們不能直接在 JSX 中使用,但是你可以將它們放在周圍的代碼中。
<MyComponent foo={1 + 2 + 3 + 4} />

function NumberDescriber(props) {
  let description;
  if (props.number % 2 == 0) {
    description = <strong>even</strong>;
  } else {
    description = <i>odd</i>;
  }
  return <div>{props.number} is an {description} number</div>;
}
你可以將字符串常量作為屬性值傳遞,react不會對其進行HTML轉義

<MyComponent message={'hello world'} />

React 組件也可以通過數組的形式返回多個元素,會按順序渲染
false、null、undefined 和 true 都是有效的子代,但它們不會直接被渲染。下面的表達式是等價的:
<div />

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{undefined}</div>

<div>{true}</div>
JavaScript 中的一些“falsy” 值(比如數字0),它們依然會被渲染
<div>
  {props.messages.length &&
    <MessageList messages={props.messages} />
  }
</div>
//當props.messages為空數組時,會打印0
要解決這個問題,請確保 && 前面的表達式始終為布爾值
<div>
  {props.messages.length > 0 &&
    <MessageList messages={props.messages} />
  }
</div>
如果你想讓類似false``true、nullundefined 出現在輸出中,你必須先把它轉換成字符串
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容