AntDesign-React與VUE有點不一樣,第一篇深入了解React的概念之一:JSX


AntDesign-React與VUE有點不一樣,第一篇深入了解React的概念之一:JSX

一、什么是JSX

使用JSX聲明一個變量(REACT當中的元素):

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

JSX是一種JavaScript的語法擴展。我們推薦在REACT中使用JSX來描述用戶界面,JSX乍一看起來可能比較像是模板語言,但事實上完全是JavaScript內部實現的。

二、為什么要使用JSX

傳統的MVC是將模板房子其他地方,比如<script>標簽或者模板文件,再在JS中通過夢中手段引用模板。按照這種思路,想想多少次我們面對四處分散的模板片段不知所措?糾結模板引擎,糾結模板存放位置,糾結如何引用模板…………下面是一段REACT官方的看法:

We strongly believe that components are the right way to separate concerns rather than "templates" and "display logic." We think that markup and the code that generates it are intimately tied together. Additionally, display logic is often very complex and using template languages to express it becomes cumbersome.
簡單來說,REACT認為組件才是王道,而組件是模板緊密關聯的,JSX這種語法,就是為了把HTML模板直接嵌入到JS代碼里面,這樣就做到了模板和組件關聯,但是JS不支持這種包含HTML的語法,所有需要通過工具將JSX編譯輸出程JS代碼才能使用。
npm install babel-loader --save-dev

三、載入方式

JSX目前有兩種方法載入。

1、內聯方式載入

<script type="text/babel">
    ReactDOM.render(
      <h1>hello landv.cn</h1>,
      document.getElementById('example')
    );
</script>

2、外聯方式載入

即將JSX代碼單獨放在一個.JSX文件中。

ReactDOM.render(
     <h1>hello landv.cn</h1>,
     document.getElementById('example')
);

然后在頁面上通過下面的方式引入這個.jsx文件。

<script type="text/babel" src="hello.jsx"></script>

四、在jSX中使用表達式

可以任意地在JSX當中使用JavaScript表達式,在JSX當中的表達式要包括在大括號里(個人理解就是寫在JS里的HTML里面的JS需要{}大括號)。

// 定義一個函數,返回傳入的名字的拼寫后的結果
function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}
// 定義一個數據類型為對象的常量
const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};
// 使用JSX語法來定義一個html標簽(所以element為小寫開頭)
const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>
);
// 渲染這個html標簽
ReactDOM.render(
  element,
  document.getElementById('root')
);

注意:

1、我們書寫JSX的時候一般都會帶上換行和縮進,這樣就可以增強代碼的可讀性。

2、與此同時,我們同樣推薦在JSX代碼的外面擴上一個小括號,這樣可以防止分號自動插入的BUG

五、JSX本身其實也是一種表達式

在編譯之后呢,JSX其實會被轉換為普通的JavaScript對象。
這也就意味着,你其實在IF或者FOR語句里面使用JSX,將它賦值給變量,當做參數傳入,作為返回值都可以:
// 定義一個函數,如果有傳參數進來就把名字拼寫好返回,否則就返回陌生人
function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

六、JSX屬性

你可以使用引號來定義以字符串為值的屬性:

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

也可以使用大括號來定義以JavaScript表達式為值的屬性:

const element = <img src={user.avatarUrl}></img>;
切記使用了大括號包裹的 JavaScript 表達式時就不要再到外面套引號了。JSX 會將引號當中的內容識別為字符串而不是表達式。(不要src="{user.avatarUrl}",會以為src為{user.avatarUrl})

七、JSX嵌套

如果JSX標簽是閉合式的,那么你需要在結尾處用/>,就好像XML/HTML一樣:
const element = <img src={user.avatarUrl} />;

JXS標簽同樣可以相互嵌套:(當換行和縮進的時候,使用括號包住它們)

const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);

警告:

因為JSX的特性更接近JavaScript而不是HTML,所以REACT DOM使用camelCase小駝峰命名來定義屬性的名字,而不是使用HTML的屬性命名。(概括就是:JSX使用小駝峰命名定義屬性的名稱)

例如,class編程了className,而tabindex則對應着tabIndex.

八、JSX防注入攻擊

你可以放心地在JSX當中使用用戶輸入:

const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element = <h1>{title}</h1>;

REACT DOM在渲染之前默認會過濾所有傳入的值,它可以確保你的引用不會被注入攻擊。所有的內容在渲染之前都被轉換成了字符串。這樣可以有效的防止XSS(跨站腳本)攻擊。

九、HTMl轉義

REACT會將所有要顯示到DOM的字符串轉義,防止XSS。所以如果JSX中包含轉義后的實體字符串比如&copy:(©)最后顯示到DOM中不會被正確顯示,因此REACT自動吧&copy;中的特殊字符轉義了。有幾種解決方法:

  • 直接使用UTF-8字符©
  • 使用對應字符的Unicode編碼,查詢編碼
  • 使用數組組裝<div>{['cc ', <span>&copy;</span>, ' 2019']}</div>
  • 直接插入原始的HTML
<div dangerouslySetInnerHTML={{__html: 'cc &copy; 2019'}} />

十、JSX代表Objects

Babel轉譯器會把JSX轉換成一個名為React.createElement()的方法調用。

下面兩種代碼的作用是完全相同的:

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

React. createElement()這個方法首先會進行一些避免BUG的檢查,之后返回一個類似下面例子的對象:

// 注意: 以下示例是簡化過的(不代表在 React 源碼中是這樣)
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world'
  }
};

這樣的對象被成為“REACT元素”。它代碼所有你在屏幕上看到的東西。

REACT通過讀取這些對象來構建DOM並保持數據內容一致。

十一、注釋

在JSX里使用注釋也很簡單,就是沿用JavaScript,唯一要注意的是在一個組件的子元素位置使用注釋要用{}包起來。

var content = (
  <Nav>
      {/* child comment, put {} around */}
      <Person
        /* multi
           line
           comment */
        name={window.isLoggedIn ? window.name : ''} // end of line comment
      />
  </Nav>
);

十二、自定義HTML屬性

如果在JSX中使用的屬性不存在與HTML的規范中,這高屬性會被忽略。如果使用自定義屬性,可以用data-前綴。

可訪問性屬性的前綴aria-也是支持的。

支持的標簽和屬性

如果你要使用的某些標簽或屬性不在這些支持列表里面就可能被REACT忽略,必須喲使用的話可以提ISSue,或者用前面提到的dangerouslySetInerHTML.

十三、屬性擴展

有時候你需要給組件設置多個屬性,你不想一個個寫下這些屬性,或者有時候你甚至不知道這些屬性的名稱,這時候spread attributes的功能就很有用了。

比如:

var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;

props對象的屬性會被設置程Component的屬性。

屬性也可以被覆蓋:

ar props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'

寫在后面的屬性值會被覆蓋前面的屬性。

ar props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'

參考資料

  1. React 官方中文文檔
  2. React 中文文檔
  3. React - JSX語法詳解(附樣例)

對對對


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM