日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
在React中實(shí)現(xiàn)條件渲染的七種方法

條件渲染方式

一、if 語(yǔ)句

先從 React 最基本的條件類型來(lái)看。如果有數(shù)據(jù)就顯示組件,如果沒(méi)有數(shù)據(jù)就不顯示任何內(nèi)容。posts 為需要渲染的列表:

export default function App() {
const { posts } = usePosts();

if (!posts) return null;

return (



);
}

這種形式會(huì)生效的原因就是我們會(huì)提前返回,如果滿足條件(posts 值不存在),就通過(guò)return null 在組件中不顯示任何內(nèi)容。

如果有多個(gè)要檢查的條件時(shí),也可以使用 if 語(yǔ)句。例如,在顯示數(shù)據(jù)之前檢查加載和錯(cuò)誤狀態(tài):

export default function App() {
const { isLoading, isError, posts } = usePosts();
if (isLoading) return
Loading...
;
if (isError) return
Error!
;
return (



);
}

這里我們可以多次使用 if 語(yǔ)句,不需要再使用 else 或者 if-eles 語(yǔ)句,這樣就減少了需要編寫(xiě)的代碼,并且可讀性更強(qiáng)。

二、三元運(yùn)算符

當(dāng)我們想提前退出或者什么都不顯示時(shí),if 語(yǔ)句會(huì)很有用。但是,如果我們不想寫(xiě)一個(gè)與返回的 JSX 分開(kāi)的條件,而是直接在其中寫(xiě)呢?那就可以使用三元表達(dá)式來(lái)編寫(xiě)條件。

在 React 中,我們必須在 JSX 中包含表達(dá)式,而不是語(yǔ)句。這就是為什么我們?cè)?JSX 中只能使用三元表達(dá)式,而不是 if 語(yǔ)句來(lái)編寫(xiě)條件。

例如,在移動(dòng)設(shè)備的屏幕上顯示一個(gè)組件,而在更大的屏幕上顯示另一個(gè)組件,就可以使用三元表達(dá)式來(lái)實(shí)現(xiàn):

export default function App() {
const isMobile = useWindowSize()

return (


{isMobile ? : }

)
}

其實(shí),不必將這些三元表達(dá)式包含在 JSX 中,可以將其結(jié)果分配給一個(gè)變量,然后在需要的地方使用即可:

export default function App() {
const isMobile = useWindowSize();
const ChatComponent = isMobile ? : ;
return (



{ChatComponent}

)
}

三、&&運(yùn)算符

在許多情況下,我們可能想要使用三元表達(dá)式,但是如果不滿足條件,就不顯示任何內(nèi)容。那代碼會(huì)是這樣的:

condition ?  : null.

可以使用 && 運(yùn)算符來(lái)簡(jiǎn)化:

export default function App() {
const { posts, hasFinished } = usePosts()
return (
<>

{hasFinished && (

已經(jīng)到底啦!


)}

)
}

如果條件為真,則邏輯 && 運(yùn)算符之后的表達(dá)式將是輸出。如果條件為假,React 會(huì)忽略并跳過(guò)表達(dá)式.

四、switch

過(guò)多的 if 語(yǔ)句會(huì)導(dǎo)致組件變得混亂,可以將多個(gè)條件提取到包含 switch 語(yǔ)句的單獨(dú)的組件中(根據(jù)組件邏輯的復(fù)雜程度來(lái)選擇是否提取到單獨(dú)的組件)。下面來(lái)看一個(gè)簡(jiǎn)單的菜單切換組件:

export default function Menu() {
const [menu, setMenu] = React.useState(1);

const toggleMenu = () => {
setMenu((m) => {
if (m === 3) return 1;
return m + 1;
});
}
return (
<>



);
}
function MenuItem({ menu }) {
switch (menu) {
case 1:
return ;
case 2:
return ;
case 3:
return ;
default:
return null;
}
}

由于使用帶有 switch 語(yǔ)句的 MenuItem 組件父菜單組件不會(huì)被條件邏輯弄亂,可以很容易地看到給定 menu 狀態(tài)將顯示哪個(gè)組件。需要注意,必須為 switch case 運(yùn)算符使用默認(rèn)值,因?yàn)樵?React 中,組件始終需要返回一個(gè)元素或 null。

五、枚舉

在 JavaScript 中,當(dāng)對(duì)象用作鍵值對(duì)的映射時(shí),它可以用作枚舉:

const ENUMOBJECT = {
a: '1',
b: '2',
c: '3',
};

假如要?jiǎng)?chuàng)建三個(gè)不同的組件 Foo、Bar 和 Default,并根據(jù)某種狀態(tài)顯示這些組件:

const Foo = () => {
return ;
};
const Bar = () => {
return ;
};
const Default = () => {
return ;
};

創(chuàng)建可用作枚舉的對(duì)象:

const ENUM_STATES = {
foo: ,
bar: ,
default:
};

渲染這個(gè)枚舉對(duì)象的函數(shù):

function EnumState({ state }) {
return
{ENUM_STATES[state]}
;
}

上面的 state 屬性可以從對(duì)象中檢索值??梢钥吹?,與 switch case 運(yùn)算符相比,它更具可讀性。

六、JSX 庫(kù)

JSX Control Statements 庫(kù)擴(kuò)展了 JSX 的功能,從而可以直接使用 JSX 實(shí)現(xiàn)條件渲染。它是一個(gè) Babel 插件,可以在轉(zhuǎn)譯過(guò)程中將類似組件的控制語(yǔ)句轉(zhuǎn)換為對(duì)應(yīng)的 JavaScript。

安裝babel-plugin-jsx-control-statements包并修改 Babel 配置后,可以像這樣重寫(xiě)應(yīng)用程序:

export default function App(props) {
const [isLoggedIn, setIsLoggedIn] = useState(false);
//...
return (


;


;


);
}

當(dāng)然,不建議這樣來(lái)編寫(xiě)條件語(yǔ)句,這樣會(huì)導(dǎo)致代碼的可讀性變差,并且 JSX 允許使用強(qiáng)大的 JavaScript 功能來(lái)自己處理?xiàng)l件渲染,無(wú)需添加模板組件即可啟用它。

七、高階組件

高階組件 (HOC)與 React 中的條件渲染完美匹配。HOC 可以幫助處理多個(gè)用例,但一個(gè)用例可能是使用條件渲染來(lái)改變組件的外觀。讓我們看看顯示元素或組件的 HOC:

function withLoadingIndicator(Component) {
return function EnhancedComponent({ isLoading, ...props }) {
if (!isLoading) {
return ;
}
return (

Loading



);
};
}
const ListWithLoadingIndicator = withLoadingIndicator(List);
function App({ list, isLoading }) {
return (

);
}

在這個(gè)例子中,List 組件可以專注于呈現(xiàn)列表。而不必再加載狀態(tài)。HOC 隱藏了實(shí)際組件中的所有干擾。最終,可以添加多個(gè)高階組件來(lái)隱藏多個(gè)條件渲染邊緣情況。

注意事項(xiàng)

一、小心 0

來(lái)看一個(gè)常見(jiàn)的渲染示例,當(dāng)數(shù)組中存在元素時(shí)才渲染內(nèi)容:

{gallery.length && }

預(yù)想的結(jié)果是,數(shù)組存在元素時(shí)渲染內(nèi)容,不存在元素時(shí)什么都不渲染。但是,頁(yè)面上得到了 “0”。這是因?yàn)樵谑褂门c運(yùn)算符時(shí),一個(gè)假的左側(cè)值(如 0)會(huì)立即返回。在JavaScript中,布爾運(yùn)算法不會(huì)將其結(jié)果轉(zhuǎn)化為布爾值。所以,React 將得到的值放入DOM中,與 false 不同的是,0 是一個(gè)有效的 React 節(jié)點(diǎn),所以最終會(huì)渲染成0。

那該如何避免這個(gè)問(wèn)題呢?可以顯式的將條件轉(zhuǎn)換為布爾值,當(dāng)表達(dá)式結(jié)果為false時(shí),就不會(huì)在頁(yè)面中渲染了:

gallery.length > 0 && jsx
!!gallery.length && jsx
Boolean(gallery.length) && jsx

或者使用三元表達(dá)式來(lái)實(shí)現(xiàn):

{gallery.length ?  : null}

二、優(yōu)先級(jí)

與運(yùn)算符(&&)比或運(yùn)算符(||)具有更高的優(yōu)先級(jí)。所以,要格外小心使用包含與運(yùn)算符的 JSX 條件:

user.anonymous || user.restricted && 

這樣寫(xiě)就相當(dāng)于:

user.anonymous || (user.restricted && 
)

這樣,與運(yùn)算符左側(cè)為真時(shí)就會(huì)直接返回,而不會(huì)繼續(xù)執(zhí)行后面的代碼。所以,多數(shù)情況下,看到或運(yùn)算符時(shí),就將其使用括號(hào)括起來(lái),避免因?yàn)閮?yōu)先級(jí)問(wèn)題而渲染出錯(cuò):

{(user.anonymous || user.restricted) && 
}

三、 嵌套三元表達(dá)式

三元表達(dá)式適合在兩個(gè)JSX之間進(jìn)行切換,一旦超過(guò)兩個(gè)項(xiàng)目,代碼就會(huì)變得糟糕:

{
isEmoji
?
: isCoupon
?
: isLoaded &&
}

有時(shí)使用 && 來(lái)實(shí)現(xiàn)會(huì)更好,不過(guò)一些條件判斷會(huì)重復(fù):

{isEmoji && }
{isCoupon && }
{!isEmoji && !isCoupon && isLoaded && }

當(dāng)然,這種情況下,使用 if 語(yǔ)句可能是更好的選擇:

const getButton = () => {
if (isEmoji) return ;
if (isCoupon) return ;
return isLoaded ? : null;
};

四、避免 JSX 作為條件

通過(guò) props 傳遞的 React 元素能不能作為判斷條件呢?來(lái)看一個(gè)簡(jiǎn)單的例子:

const Wrap = (props) => {
if (!props.children) return null;
return
{props.children}

};

我們希望 Wrap 在沒(méi)有包含內(nèi)容時(shí)呈現(xiàn) null,但 React 不是這樣工作的:

  • props.children 可以是一個(gè)空數(shù)組,例如 {[].map(e =>
    )}。
  • children.length 也失敗了:children 也可以是單個(gè)元素,而不是數(shù)組,例如:(
    )。
  • React.Children.count(props.children)支持單個(gè)子項(xiàng)和多個(gè)子項(xiàng),但會(huì)認(rèn)為 {false && 'hi'}{false && 'there'}包含 2 個(gè)項(xiàng),而實(shí)際上有沒(méi)有任何子項(xiàng)。
  • React.Children.toArray(props.children) 移除無(wú)效節(jié)點(diǎn),例如 false。然而,對(duì)于一個(gè)空片段,仍然是正確的:<>。
  • 如果將條件渲染移動(dòng)到組件內(nèi):
    與 Div = (p) => p.hide ?null :
    ,在 Wrap 渲染時(shí)永遠(yuǎn)無(wú)法知道它是否為空,因?yàn)?react 只會(huì)在父級(jí)之后渲染子級(jí) div,而有狀態(tài)的子級(jí)可以獨(dú)立于其父級(jí)重新渲染。

因此,不要將JSX作為判斷條件,避免出現(xiàn)一些難以預(yù)料的問(wèn)題。

五、重新掛載還是更新?

用三元表達(dá)式編寫(xiě)的 JSX 感覺(jué)就像是完全獨(dú)立的代碼:

{hasItem ?  : }

當(dāng) hasItem 改變時(shí)會(huì)發(fā)生什么?我的猜測(cè)是 卸載,然后 安裝,因?yàn)檫@里寫(xiě)了 2 個(gè)單獨(dú)的 JSX 標(biāo)簽。然而,React 并不知道也不關(guān)心我們寫(xiě)了什么,它所看到的只是 Item 元素在同一個(gè)位置,所以它保持掛載的實(shí)例,更新 props。上面的代碼等價(jià)于???? 。

注意:如果三元表達(dá)式包含的是不同的組件,如 {hasItem ? : },hasItem改變時(shí),React 會(huì)重新掛載,因?yàn)?Item1 無(wú)法更新為 Item2。

上述情況會(huì)導(dǎo)致一些意外的行為:

{
mode === 'name'
?
:
}

這里,如果在 name 的 input 中輸入了一些內(nèi)容,然后切換模式(mode),在 name 中輸入內(nèi)容的就會(huì)泄漏到 phone 的 input 中,這可能會(huì)對(duì)依賴于先前狀態(tài)的復(fù)雜更新機(jī)制造成更大的破壞。

這里的一種解決方法是使用 key。通常,我們用它來(lái)渲染列表,但它實(shí)際上是 React 的元素標(biāo)識(shí)提示——具有相同 key 的元素是相同的邏輯元素:

{
mode === 'name'
?
:
}

另一種方法是用兩個(gè)單獨(dú)的 && 塊來(lái)替換三元表達(dá)式。當(dāng) key 不存在時(shí),React 會(huì)回退到子數(shù)組中項(xiàng)目的索引,因此將不同的元素放在不同的位置與顯式定義 key 的效果是一樣的:

{mode === 'name' && }
{mode !== 'name' && }

參考:

https://blog.thoughtspile.tech/2022/01/17/jsx-conditionals/。

https://ordinarycoders.com/blog/article/react-conditional-rendering。


網(wǎng)站名稱:在React中實(shí)現(xiàn)條件渲染的七種方法
網(wǎng)頁(yè)地址:http://www.5511xx.com/article/cddpcis.html