日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

深入理解JSX

發(fā)布時(shí)間:2024/6/21 综合教程 29 生活家
生活随笔 收集整理的這篇文章主要介紹了 深入理解JSX 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文由筆者翻譯自官方文檔的JSX In Depth,若干案例經(jīng)過了改寫。其實(shí)說白了也好像不算太深入,但還是提示了一些可能的盲區(qū)。

JSX是為構(gòu)造React元素方法React.createElement(component, props, ...children)設(shè)計(jì)的語法糖。

比方說JSX代碼:

<Elem color="red" info="hello">Hello!<Elem/>

用標(biāo)準(zhǔn)的React語法寫出來應(yīng)該是:

React.creatElement({
  Elem,
  {
    color:red,
  	info:"hello"
  },
  "Hello!"
});

當(dāng)沒有內(nèi)容時(shí),根據(jù)xml的語法特性,可以加上自閉合標(biāo)簽:

<Elem color="red" info="hello" />

那么React語法是這樣:

React.creatElement({
  Elem,
  {
    color:red,
  	info:"hello"
  },
  null//啥內(nèi)容都沒有
});

如果你想測試JSX和javascript語法的轉(zhuǎn)換,可以點(diǎn)這里。


特殊的React元素規(guī)則

JSX標(biāo)簽的第一部分決定了React元素的類型。

JSX標(biāo)簽首字母必須要大寫,這樣做實(shí)際上聲明了:這個(gè)標(biāo)簽是一個(gè)React元素。

這個(gè)React標(biāo)簽被編譯成一個(gè)直接引用命名的變量,因此,當(dāng)你使用諸如 < Foo / >這樣的JSX表達(dá)式時(shí),Foo必須在React作用范圍內(nèi)。

必須在React作用范圍內(nèi)

當(dāng)你用React.createElement調(diào)用JSX, 必須引入React庫。

例如,下面的每個(gè)import都是必要的——盡管React和CustomButton不是直接從JavaScript引用:

import React from 'react';
import CustomButton from './CustomButton';

function WarningButton() {
  // return React.createElement(CustomButton, {color: 'red'}, null);
  return <CustomButton color="red" />;
}

如果你不使用javascript打包工具或是不在腳本標(biāo)簽引用,上面這種寫法就讓你的標(biāo)簽就在React的全局作用范圍內(nèi)了。

JSX支持使用點(diǎn)符號

你也可以在React組件的JSX標(biāo)簽中使用點(diǎn)符號(.)。 如果你有一個(gè)專門用來輸出組件的模塊,里面塞滿了各種React組件,使用點(diǎn)符號調(diào)用會很方便。 比方說,如果MyComponents. DatePicker是一個(gè)組件,你可以直接用JSX語法寫為:

import React from 'react';

const MyComponents = {
  DatePicker: function DatePicker(props) {
    return <div>Imagine a {props.color} datepicker here.</div>;
  }
}

function BlueDatePicker() {
  return <MyComponents.DatePicker color="blue" />;
}

用戶自定義的組件首字母必須大寫

如果一個(gè)React元素以小寫字母開頭,意味著它是一個(gè)內(nèi)置組件(如< div >或< span >)。結(jié)果是把一個(gè)字符串諸如“div”或“span”傳遞給React.createElement方法。 如果以大寫字母開頭,比如< Foo / >編譯的結(jié)果是:React.createElement(Foo),相應(yīng)地將生成一個(gè)自定義的組件,并導(dǎo)入到你的JavaScript文件中。

請以大寫字母命名組件。如果你不方便這么做,那就在使用JSX語法前編譯一下你的命名,分配一個(gè)大寫的變量名。

例如,這段代碼將不會像預(yù)期的那樣運(yùn)行:

import React from 'react';

// 錯(cuò)了,首字母必須大寫
function hello(props) {
  // 正確!因?yàn)閐iv是html自帶的標(biāo)簽
  return <div>Hello {props.toWhat}</div>;
}

function HelloWorld() {
  // 錯(cuò)了,React會把“hello”理解為一個(gè)html標(biāo)簽。
  return <hello toWhat="World" />;
}

綜上,只要把上面代碼的hello改為Hello就可以了。

在運(yùn)行時(shí)選擇標(biāo)簽名

在React元素里面,你不能使用一般的javascript表達(dá)式。如果你想使用一個(gè)通用表達(dá)式來表示元素,先分配一個(gè)大寫變量名給它。你渲染一個(gè)基于props的組件時(shí),經(jīng)常會遇到這個(gè)問題:

import React from 'react';
import { PhotoStory, VideoStory } from './stories';

const components = {
  photo: PhotoStory,
  video: VideoStory
};

function Story(props) {
  // 錯(cuò)了!JSX不接受表達(dá)式
  return <components[props.storyType] story={props.story} />;
}

正確的做法是:

...
function Story(props) {
  // 對啦。JSX可以接受一個(gè)大寫開頭的變量名
  const SpecificStory = components[props.storyType];
  return <SpecificStory story={props.story} />;
}

JSX中的props

有幾種不同的方式來指定在JSX中的props。

JavaScript表達(dá)式

props可以是任何javascript的表達(dá)式——但是得用{ }包起來。 例如,在這JSX中:

var a='zzz';
...
<App name={'xxx'+a+'yyy'}/>

Appprops.name將會計(jì)算為xxxzzzyyy

if語句h和for循環(huán)不是javascript的表達(dá)式,所以你不可以直接把它們作為props的值。相應(yīng)地,你可以這樣做:

...
var a=null;

if(this.props.b%2===0){
  a=<div>偶數(shù)</div>
}else{
  a=<div>奇數(shù)</div>
}
return (
	<div>{this.props.b}是{a}</div>
)
...

字符串字面量

只要不是表達(dá)式,你就可以直接傳遞一個(gè)字符串作為props,而不沒有用花括號包著。 這兩個(gè)JSX表達(dá)式是等價(jià)的:

...
<App name="xxx&lt;yyy"/>
//或者這樣
<App name={"xxx>yyy"}>

props默認(rèn)為True

如果你沒有給props傳值,那它默認(rèn)值就是true。如假包換的true。

所以以下兩個(gè)表達(dá)式基本上是等價(jià)的

//這樣可以
<App name={true}/>
//這樣也行
<App name/>

但是第二種用法在ES6語法中容易被混淆為<App name={name}/>,所以不建議這樣用。

傳播屬性

如果你已經(jīng)把props作為一個(gè)對象,你想用JSX統(tǒng)統(tǒng)添加進(jìn)組件,你可以使用把整個(gè)props對象分享出去。 這兩個(gè)組件是等價(jià)的:

//寫法1
function App1() {
  return <Greeting firstName="Ben" lastName="Hector" />;
}
//寫法2:看起來是不是方便了很多呢?
function App2() {
  var xxx = {firstName: 'Ben', lastName: 'Hector'};
  return <Greeting {...xxx} />;
}

當(dāng)你構(gòu)建一個(gè)大型的組件盒子,這個(gè)方法看起來很好用。但是{...xxx}方法太暴力了,可能一次性給你的組件傳遞了許多無關(guān)緊要的props——從而導(dǎo)致代碼混亂。因此在使用前應(yīng)該慎重。


JSX的children

JSX表達(dá)式中,必然包含一個(gè)開始標(biāo)記和結(jié)束標(biāo)記——開始標(biāo)簽和閉合標(biāo)簽之間的內(nèi)容是一個(gè)特殊的props——props.children。有以下幾種類型的數(shù)據(jù)都可以作為children

字符串字面量

如果你在開始標(biāo)記之間放的是一個(gè)字符串,那么你的props.children就是這個(gè)字符串——而且還不用打引號。換言之你可以直接塞你需要的html內(nèi)容:

<App>Hello!</App>

<div>hello!</div>
//看起來和html沒區(qū)別吧

JSX還可以刪除在一行的開始和結(jié)束之間的空格。 同時(shí)還能刪除空白行。 行的相鄰標(biāo)記將被切掉。所以以下寫法都一樣:

<div>hello world!</div>

<div>hello 
world!
</div>

<div>
  
  hello
  world!
</div>

JSX組件的子代

在組件嵌套時(shí),基本上你可以盡情地將子組件加進(jìn)去。這些嵌套的內(nèi)容都是props.children。

<MyContainer>
  <MyFirstComponent />
  <MySecondComponent />
</MyContainer>

//或者這樣
<ul>
  <li>haha</li>
  <li>hehehe</li>
  ...
</ul>

但為什么說”基本上“呢?只有一個(gè)原則需要把握,就是一個(gè)React組件只能返回一個(gè)頂層對象——要么就用一個(gè)div包起來。這是入門時(shí)就反復(fù)提及的問題。

javascript表達(dá)式

javascript表達(dá)式用{}抱起來就可以了。這在遍歷方法時(shí)非常實(shí)用:

var App=React.createClass({
  render:function(){
    var arr=[];
    for(var i=0;i<6;i++){
      var content=<li key={i.toString}>我是第{i+1}行</li>
      arr.push(content);
    }
    
    return (
    	<ul>{arr}</ul>
    );
  }
});

函數(shù)

通常,JavaScript表達(dá)式插入JSX,將被解釋為一個(gè)字符串,或一個(gè)React元素,或一串這些東西。 更有趣的是,props.children的行為與其它props沒什么不同,不僅可以放用來渲染的內(nèi)容,還可以放函數(shù),方法。 例如,如果你有一個(gè)自定義組件,你可以把props.children作為回調(diào):

var ListTen=React.createClass({
        content:function(index){
            return (
                <div key={index}>這是列表的第{index}項(xiàng)</div>
            )
        },
        render:function(){
            return (
                <Repeat times={10}>
                  {this.content}
                </Repeat>
            );//這里把方法函數(shù)content作為一個(gè)Repeat組件的props.children

        }
    });
	
    var Repeat=React.createClass({
        render:function(){
            var arr=[];
            for(var i=0;i<this.props.times;i++){
              arr.push(this.props.children(i));
            }//每循環(huán)一次就調(diào)用props.children的方法

            return (
                <div>{arr}</div>
            );
        }
    });

    ReactDOM.render(
        <ListTen/>,
        document.getElementById('example')
    );

可見children可以是任何東西——只要React在渲染之前能夠理解它。盡管以上代碼思路不太常見,但是只要多嘗試,就會發(fā)現(xiàn)React的內(nèi)涵。

布爾值,空對象和未定義將被無視

false,?null,?undefined還有?true?對children來說都是可以放的。但是這對渲染而言沒有意義——React在渲染前簡單地把他們忽略掉了。所以你用他們企圖改變渲染,什么也得不到:

<div />

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{true}</div>

看起來好像什么都沒有用。但這是條件渲染的基本實(shí)現(xiàn)思路:

<div>
  {showHeader && <Header />}
  <Content />
</div

上面的代碼中,如果showHeader為false,那它將只執(zhí)行<Header/>。

此外常見的假值中,0是可以被渲染的。

<div>
  {props.messages.length &&
    <MessageList messages={props.messages} />
  }
</div>

如上,如果props.messages不存在,props.messages.length值就為0,結(jié)果0就被渲染進(jìn)去了。

因此,你最好保證你代碼中&&的前面是一個(gè)布爾值——比如props.messages.length>0就是一個(gè)不錯(cuò)的選擇。

對于被無視掉的內(nèi)容,這樣寫當(dāng)然是錯(cuò)的:

<div>
	true  
</div>

對于這個(gè)children,你應(yīng)該這樣寫——<div>{'true'}</div>,如果是變量,就用字符串方法把它轉(zhuǎn)一下。

總結(jié)

以上是生活随笔為你收集整理的深入理解JSX的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。